找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
热搜: 活动 交友 discuz
查看: 125|回复: 0

AI 智能游戏编程

[复制链接]

355

主题

217

回帖

2073

积分

管理员

积分
2073
发表于 2025-2-10 09:21:35 | 显示全部楼层 |阅读模式
FIRST INSTALL
一、deepseek本地模型 下载
* 1.1 ollama下载
   https://ollama.com/download
* 1.2 deepseek-r1 下载
export OLLAMA_HOST=0.0.0.0:11434
   ollama run deepseek-r1:7b
* 1.3 pageassisnt chrome 插件安装

* 1.4 本地访问ollama服务
cmd
curl -X POST http://localhost:11434/api/generate \
     -H "Content-Type: application/json" \
     -d '{
           "model": "deepseek-r1:7b",
           "prompt": "What is the capital of France?",
           "stream": false
         }'

node js
  1. app.post('/generate', async (req, res) => {
  2.     const {  prompt } = req.body;
  3.     var model="deepseek-r1:7b"
  4.     var stream=false

  5.    console.log({
  6.             model: model,
  7.             prompt: prompt,
  8.             stream: stream
  9.         }, {
  10.             headers: {
  11.                 'Content-Type': 'application/json'
  12.             }
  13.         })
  14.     try {
  15.         const response = await axios.post('http://localhost:11434/api/generate', {
  16.             model: model,
  17.             prompt: prompt,
  18.             stream: stream
  19.         }, {
  20.             headers: {
  21.                 'Content-Type': 'application/json'
  22.             }
  23.         });
  24.                console.log(response)  
  25.         res.send(response.data.response);
  26.     } catch (error) {
  27.         console.error('Error accessing deepseekr1 model:', error);
  28.         res.status(500).send('Internal Server Error');
  29.     }
  30. });
复制代码


复制代码



二、游戏下载
1、phaser
cnpm install phaser axios body-parse express http


node server2.js
  1. const express = require('express');
  2. const axios = require('axios');
  3. const bodyParser = require('body-parser');
  4. const path = require('path');
  5. const app = express();
  6. const PORT = 3000; // 你可以根据需要更改端口

  7. app.use(bodyParser.json());


  8. app.use(bodyParser.json());
  9. app.use(bodyParser.urlencoded({ extended: true }));

  10. // 设置public文件夹为静态文件目录
  11. app.use(express.static(path.join(__dirname, 'public')));


  12. app.post('/generatejson', async (req, res) => {
  13.     const {  prompt } = req.body;
  14.     var model="deepseek-r1:7b"
  15.     var stream=false

  16.    console.log({
  17.             model: model,
  18.             prompt: prompt,
  19.             stream: stream
  20.         }, {
  21.             headers: {
  22.                 'Content-Type': 'application/json'
  23.             }
  24.         })
  25.     try {
  26.         const response = await axios.post('http://localhost:11434/api/generate', {
  27.             model: model,
  28.             prompt: prompt,
  29.             stream: stream
  30.         }, {
  31.             headers: {
  32.                 'Content-Type': 'application/json'
  33.             }
  34.         });
  35.         console.log(response)
  36.         res.send(response.data);
  37.     } catch (error) {
  38.         console.error('Error accessing deepseekr1 model:', error);
  39.         res.status(500).send('Internal Server Error');
  40.     }
  41. });



  42. app.post('/generate', async (req, res) => {
  43.     const {  prompt } = req.body;
  44.     var model="deepseek-r1:7b"
  45.     var stream=false

  46.    console.log({
  47.             model: model,
  48.             prompt: prompt,
  49.             stream: stream
  50.         }, {
  51.             headers: {
  52.                 'Content-Type': 'application/json'
  53.             }
  54.         })
  55.     try {
  56.         const response = await axios.post('http://localhost:11434/api/generate', {
  57.             model: model,
  58.             prompt: prompt,
  59.             stream: stream
  60.         }, {
  61.             headers: {
  62.                 'Content-Type': 'application/json'
  63.             }
  64.         });
  65.                console.log(response)  
  66.         res.send(response.data.response);
  67.     } catch (error) {
  68.         console.error('Error accessing deepseekr1 model:', error);
  69.         res.status(500).send('Internal Server Error');
  70.     }
  71. });

  72. app.listen(PORT, () => {
  73.     console.log(`Server is running on http://localhost:${PORT}`);
  74. });
复制代码

复制代码


2、游戏案例
  1. <!doctype html>
  2. <html lang="en">
  3. <head>
  4.     <meta charset="UTF-8" />
  5.     <title>Making your first Phaser 3 Game - Part 10</title>
  6.     <script src="lib/phaser.min.js"></script>
  7.     <style type="text/css">
  8.         body {
  9.             margin: 0;
  10.         }
  11.         #game-container {
  12.             position: relative;
  13.         }
  14.         #input-container {
  15.             position: absolute;
  16.             bottom: 10px;
  17.             width: 100%;
  18.             text-align: center;
  19.         }
  20.         #input-box {
  21.             padding: 10px;
  22.             font-size: 16px;
  23.             width: 300px;
  24.         }
  25.         #send-button {
  26.             padding: 10px;
  27.             font-size: 16px;
  28.         }
  29.         #npc-selector {
  30.             padding: 10px;
  31.             font-size: 16px;
  32.             margin-right: 10px;
  33.         }
  34.     </style>
  35. </head>
  36. <body>

  37. <div id="game-container">
  38. </div>
  39. <div id="input-container">
  40.     <select id="npc-selector">
  41.         <option value="greengirl">Green Girl</option>
  42.         <option value="bluegirl">Blue Girl</option>
  43.         <option value="yellowman">Yellow Man</option>
  44.     </select>
  45.     <input type="text" id="input-box" placeholder="Type your message here...">
  46.     <button id="send-button">Send</button>
  47. </div>

  48. <script type="text/javascript">

  49. var config = {
  50.     type: Phaser.AUTO,
  51.     width: 1000,
  52.     height: 600,
  53.     physics: {
  54.         default: 'arcade',
  55.         arcade: {
  56.             gravity: { y: 300 },
  57.             debug: false
  58.         }
  59.     },
  60.     scene: {
  61.         preload: preload,
  62.         create: create,
  63.         update: update
  64.     }
  65. };

  66. var player;
  67. var npc; // NPC character
  68. var stars;
  69. var bombs;
  70. var platforms;
  71. var cursors;
  72. var playerScore = 0;
  73. var npcScore = 16;
  74. var gameOver = false;
  75. var scoreText;
  76. var npcScoreText;
  77. var dialogueBox;
  78. var dialogueText;
  79. var npcDialogueBox;
  80. var npcDialogueText;
  81. var isWaitingResponse = false;
  82. var npcIsWaitingResponse = false;
  83. var playerHitBomb = false;
  84. var npcHitBomb = false;
  85. var npcSkin='greengirl';
  86. var game = new Phaser.Game(config);

  87. function preload () {
  88.     this.load.image('sky', 'assets/sky.png');
  89.     this.load.image('ground', 'assets/platform.png');
  90.     this.load.image('star', 'assets/star.png');
  91.     this.load.image('bomb', 'assets/bomb.png');
  92.     this.load.spritesheet('dude', 'assets/dude.png', { frameWidth: 32, frameHeight: 48 });
  93.     this.load.spritesheet('greengirl', 'assets/greengirl.png', { frameWidth: 32, frameHeight: 48 });
  94.     this.load.spritesheet('bluegirl', 'assets/bluegirl.png', { frameWidth: 32, frameHeight: 48 });
  95.     this.load.spritesheet('yellowman', 'assets/yellowman.png', { frameWidth: 32, frameHeight: 48 });
  96. }

  97. function create () {
  98.     //  A simple background for our game
  99.     this.add.image(400, 300, 'sky');

  100.     //  The platforms group contains the ground and the 2 ledges we can jump on
  101.     platforms = this.physics.add.staticGroup();

  102.     //  Here we create the ground.
  103.     //  Scale it to fit the width of the game (the original sprite is 400x32 in size)
  104.     platforms.create(400, 568, 'ground').setScale(2).refreshBody();

  105.     //  Now let's create some ledges
  106.     platforms.create(600, 400, 'ground');
  107.     platforms.create(50, 250, 'ground');
  108.     platforms.create(750, 220, 'ground');

  109.     // The player and its settings
  110.     player = this.physics.add.sprite(100, 450, 'dude');
  111.     player.setBounce(0.2);
  112.     player.setCollideWorldBounds(true);

  113.     //  Our player animations, turning, walking left and walking right.
  114.     this.anims.create({
  115.         key: 'left',
  116.         frames: this.anims.generateFrameNumbers('dude', { start: 0, end: 3 }),
  117.         frameRate: 10,
  118.         repeat: -1
  119.     });

  120.     this.anims.create({
  121.         key: 'turn',
  122.         frames: [ { key: 'dude', frame: 4 }],
  123.         frameRate: 20
  124.     });

  125.     this.anims.create({
  126.         key: 'right',
  127.         frames: this.anims.generateFrameNumbers('dude', { start: 5, end: 8 }),
  128.         frameRate: 10,
  129.         repeat: -1
  130.     });

  131.     // Create NPC
  132.     npc = this.physics.add.sprite(700, 450, 'greengirl');
  133.     npc.setBounce(0.2);
  134.     npc.setCollideWorldBounds(true);

  135.     var npcSkins = ['greengirl', 'bluegirl', 'yellowman'];
  136.     npcSkins.forEach(snpcSkin => {
  137.         this.anims.create({
  138.             key: snpcSkin + 'left',
  139.             frames: this.anims.generateFrameNumbers(snpcSkin, { start: 4, end: 7 }),
  140.             frameRate: 10,
  141.             repeat: -1
  142.         });

  143.         this.anims.create({
  144.             key: snpcSkin + 'turn',
  145.             frames: [ { key: snpcSkin, frame: 0 }],
  146.             frameRate: 20
  147.         });

  148.         this.anims.create({
  149.             key: snpcSkin + 'right',
  150.             frames: this.anims.generateFrameNumbers(snpcSkin, { start: 8, end: 11 }),
  151.             frameRate: 10,
  152.             repeat: -1
  153.         });
  154.     });

  155.     //  Input Events
  156.     cursors = this.input.keyboard.createCursorKeys();

  157.     //  Some stars to collect, 12 in total, evenly spaced 70 pixels apart along the x axis
  158.     stars = this.physics.add.group({
  159.         key: 'star',
  160.         repeat: 11,
  161.         setXY: { x: 12, y: 0, stepX: 70 }
  162.     });

  163.     stars.children.iterate(function (child) {
  164.         child.setBounceY(Phaser.Math.FloatBetween(0.4, 0.8));
  165.     });

  166.     bombs = this.physics.add.group();

  167.     //  The score
  168.     scoreText = this.add.text(16, 16, 'Player Score: 0', { fontSize: '32px', fill: '#000' });
  169.     npcScoreText = this.add.text(400, 16, 'NPC Score: 0', { fontSize: '32px', fill: '#000' });

  170.     //  Collide the player and the stars with the platforms
  171.     this.physics.add.collider(player, platforms);
  172.     this.physics.add.collider(stars, platforms);
  173.     this.physics.add.collider(bombs, platforms);

  174.     //  Checks to see if the player overlaps with any of the stars, if he does call the collectStar function
  175.     this.physics.add.overlap(player, stars, collectStar, null, this);

  176.     // Create dialogue box (hidden initially)
  177.     dialogueBox = this.add.rectangle(player.x, player.y - 50, 200, 50, 0x000000, 0.8);
  178.     dialogueBox.visible = false;

  179.     // Create dialogue text
  180.     dialogueText = this.add.text(player.x, player.y - 50, '', { font: '16px Arial', fill: '#ffffff', align: 'center' });
  181.     dialogueText.setOrigin(0.5, 0.5);
  182.     dialogueText.visible = false;

  183.     // Create NPC dialogue box (hidden initially)
  184.     npcDialogueBox = this.add.rectangle(npc.x, npc.y - 50, 200, 50, 0x000000, 0.8);
  185.     npcDialogueBox.visible = false;

  186.     // Create NPC dialogue text
  187.     npcDialogueText = this.add.text(npc.x, npc.y - 50, '', { font: '16px Arial', fill: '#ffffff', align: 'center' });
  188.     npcDialogueText.setOrigin(0.5, 0.5);
  189.     npcDialogueText.visible = false;

  190.     // Add event listener to the send button
  191.     document.getElementById('send-button').addEventListener('click', sendDialogue);

  192.     // Add event listener to the input box for Enter key
  193.     document.getElementById('input-box').addEventListener('keypress', function(event) {
  194.         if (event.key === 'Enter') {
  195.             sendDialogue();
  196.         }
  197.     });

  198.     this.physics.add.collider(npc, platforms);
  199.     // NPC collects stars
  200.     this.physics.add.overlap(npc, stars, npcCollectStar, null, this);

  201.     this.physics.add.collider(player, bombs, hitBomb, null, this);
  202.     this.physics.add.collider(npc, bombs, hitBomb, null, this);

  203.     // Add event listener to NPC selector
  204.     document.getElementById('npc-selector').addEventListener('change', changeNPC);

  205.     // Add collision between player and NPC
  206.     this.physics.add.collider(player, npc, onCollide, null, this);
  207. }

  208. function update () {
  209.     if (gameOver) {
  210.         return;
  211.     }

  212.     if (!playerHitBomb) {
  213.         if (cursors.left.isDown) {
  214.             player.setVelocityX(-160);
  215.             player.anims.play('left', true);
  216.         } else if (cursors.right.isDown) {
  217.             player.setVelocityX(160);
  218.             player.anims.play('right', true);
  219.         } else {
  220.             player.setVelocityX(0);
  221.             player.anims.play('turn');
  222.         }

  223.         if (cursors.up.isDown && player.body.touching.down) {
  224.             player.setVelocityY(-330);
  225.         }
  226.         if (cursors.down.isDown) {
  227.             player.setVelocityY(600); // Accelerate downward movement when 'S' key is pressed
  228.         }
  229.     }

  230.     if (!npcHitBomb) {
  231.         // NPC movement using ASWD keys
  232.         if (this.input.keyboard.addKey(Phaser.Input.Keyboard.KeyCodes.A).isDown) {
  233.             npc.setVelocityX(-160);
  234.             npc.anims.play(npcSkin+'left', true);
  235.         } else if (this.input.keyboard.addKey(Phaser.Input.Keyboard.KeyCodes.D).isDown) {
  236.             npc.setVelocityX(160);
  237.             npc.anims.play(npcSkin+'right', true);
  238.         } else {
  239.             npc.setVelocityX(0);
  240.             npc.anims.play(npcSkin+'turn');
  241.         }

  242.         if (this.input.keyboard.addKey(Phaser.Input.Keyboard.KeyCodes.W).isDown && npc.body.touching.down) {
  243.             npc.setVelocityY(-330);
  244.             if (!npcIsWaitingResponse) {
  245.                 fetchJoke();
  246.             }
  247.         }
  248.         if (this.input.keyboard.addKey(Phaser.Input.Keyboard.KeyCodes.S).isDown) {
  249.             npc.setVelocityY(600); // Accelerate downward movement when 'S' key is pressed
  250.         }
  251.     }

  252.     // Update dialogue box position based on player position
  253.     dialogueBox.x = player.x;
  254.     dialogueText.x = player.x;
  255.     dialogueBox.y = player.y-50;
  256.     dialogueText.y = player.y-50;

  257.     // Update NPC dialogue box position based on NPC position
  258.     npcDialogueBox.x = npc.x;
  259.     npcDialogueText.x = npc.x;
  260.     npcDialogueBox.y = npc.y-50;
  261.     npcDialogueText.y = npc.y-50;
  262. }

  263. function collectStar (player, star) {
  264.     star.disableBody(true, true);
  265.     playerScore += 10;
  266.     scoreText.setText('Player Score: ' + playerScore);

  267.     if (stars.countActive(true) === 0) {
  268.         stars.children.iterate(function (child) {
  269.             child.enableBody(true, child.x, 0, true, true);
  270.         });

  271.         var x = (player.x < 400) ? Phaser.Math.Between(400, 800) : Phaser.Math.Between(0, 400);
  272.         var bomb = bombs.create(x, 16, 'bomb');
  273.         bomb.setBounce(1);
  274.         bomb.setCollideWorldBounds(true);
  275.         bomb.setVelocity(Phaser.Math.Between(-200, 200), 20);
  276.         bomb.allowGravity = false;
  277.     }
  278. }

  279. function npcCollectStar (npc, star) {
  280.     star.disableBody(true, true);
  281.     npcScore += 10;
  282.     npcScoreText.setText('NPC Score: ' + npcScore);

  283.     if (stars.countActive(true) === 0) {
  284.         stars.children.iterate(function (child) {
  285.             child.enableBody(true, child.x, 0, true, true);
  286.         });

  287.         var x = (npc.x < 400) ? Phaser.Math.Between(400, 800) : Phaser.Math.Between(0, 400);
  288.         var bomb = bombs.create(x, 16, 'bomb');
  289.         bomb.setBounce(1);
  290.         bomb.setCollideWorldBounds(true);
  291.         bomb.setVelocity(Phaser.Math.Between(-200, 200), 20);
  292.         bomb.allowGravity = false;
  293.     }
  294. }

  295. function hitBomb (character, bomb) {
  296.     if (character === player) {
  297.         playerHitBomb = true;
  298.         character.setVelocity(0);
  299.         character.setTint(0xff0000);
  300.         character.anims.play('turn');
  301.     } else {
  302.         npcHitBomb = true;
  303.         character.setVelocity(0);
  304.         character.setTint(0xff0000);
  305.         character.anims.play(npcSkin+'turn');
  306.     }
  307.     if (playerHitBomb && npcHitBomb) {
  308.         gameOver = true;
  309.         this.physics.pause();
  310.     }
  311. }

  312. function onCollide (player, npc) {
  313.     // Calculate the angle of collision
  314.     var angle = Phaser.Math.Angle.Between(player.x, player.y, npc.x, npc.y);
  315.     // Calculate the force vector
  316.     var force = 100; // Increase force for stronger hit
  317.     var fx = Math.cos(angle) * force;
  318.     var fy = Math.sin(angle) * force;
  319.     // Apply the force to both characters
  320.     player.setVelocityX(player.x -100 );
  321.     player.setVelocityY(player.y + 10);
  322.     npc.setVelocityX(npc.x +100);
  323.     npc.setVelocityY(npc.y - 10 );
  324.     // Play hit animation
  325.     player.anims.play('turn');
  326.     npc.anims.play(npcSkin+'turn');
  327. }

  328. function sendDialogue() {
  329.     if (isWaitingResponse) return;

  330.     const inputBox = document.getElementById('input-box');
  331.     const message = inputBox.value.trim();
  332.     dialogueBox.visible = false;
  333.     dialogueText.visible = false;
  334.     if (message === '') return;
  335.     dialogueBox.x = player.x;
  336.     dialogueText.x = player.x;
  337.     dialogueBox.y = player.y-50;
  338.     dialogueText.y = player.y-50;
  339.     // Show dialogue box and text
  340.     dialogueBox.visible = true;
  341.     dialogueText.visible = true;
  342.     dialogueText.setText('Thinking...');
  343.     isWaitingResponse = true;

  344.     // Send request to Node backend
  345.     fetch('generatejson', {
  346.         method: 'POST',
  347.         headers: {
  348.             'Content-Type': 'application/json'
  349.         },
  350.         body: JSON.stringify({ prompt: '你叫糖豆,你喜欢吃大蒜,请十八字以内回答:' + message })
  351.     })
  352.     .then(response => response.json())
  353.     .then(data => {
  354.         console.log(data);
  355.         dialogueText.setText(data.response.replace(/<think>[\s\S]*?<\/think>/g, '').trim());
  356.         isWaitingResponse = false;
  357.     })
  358.     .catch(error => {
  359.         console.error('Error:', error);
  360.         dialogueText.setText('Failed to get response');
  361.         isWaitingResponse = false;
  362.     });

  363.     // Clear input box
  364.     inputBox.value = '';
  365. }

  366. function fetchJoke() {
  367.     if (npcIsWaitingResponse) return;

  368.     npcDialogueBox.visible = true;
  369.     npcDialogueText.visible = true;
  370.     npcDialogueText.setText('Thinking...');
  371.     npcIsWaitingResponse = true;

  372.     fetch('generatejson', {
  373.         method: 'POST',
  374.         headers: {
  375.             'Content-Type': 'application/json'
  376.         },
  377.         body: JSON.stringify({ prompt: '我是糖豆老爸,给我一个俏皮话,十八个字以内' })
  378.     })
  379.     .then(response => response.json())
  380.     .then(data => {
  381.         console.log(data);
  382.         npcDialogueText.setText(data.response.replace(/<think>[\s\S]*?<\/think>/g, '').trim());
  383.         npcIsWaitingResponse = false;
  384.     })
  385.     .catch(error => {
  386.         console.error('Error:', error);
  387.         npcDialogueText.setText('Failed to get response');
  388.         npcIsWaitingResponse = false;
  389.     });
  390. }

  391. function changeNPC() {
  392.     const npcSelector = document.getElementById('npc-selector');
  393.     const selectedNPC = npcSelector.value;
  394.     console.log(selectedNPC)
  395.     npcSkin=selectedNPC
  396.     npc.setTexture(selectedNPC);
  397.     npc.setOrigin(0.5);
  398.     npc.setFrame(0);
  399. }

  400. </script>

  401. </body>
  402. </html>
复制代码


复制代码



3、素材下载
游戏模版:

图片素材:
https://www.aigei.com/view/72345.html?page=9#resContainer

4、 AI增强
1、chat.deepseek.com
2、https://kimi.moonshot.cn/chat/cujgsroh8njmu15ru2rg




本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

×
差享网住酒店送SPA服务
600元一晚送足疗,1200元两晚送柔式按摩,1800元三晚送高端SPA。更多定制服务请联系客服
点击扫码加客服微信
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|手机版|小黑屋|差享网

GMT+8, 2025-5-5 01:30 , Processed in 0.048514 second(s), 28 queries .

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表