[我正在Love2d上构建一个简单的射击游戏,起初看起来一切都很流畅,但是后来我添加了检查碰撞功能后,我试图打开游戏,但收到了“未响应”消息。所以我不确定这里出了什么问题。
我使用来自love2d论坛的碰撞功能。它不断发出“将数字与nil进行比较”的消息,并且在我设置了一些游戏状态条件后,它给了我“不响应”的消息。下面是我的代码。
Main.lua
WIDTH = 480
HEIGHT = 800
Class = require 'Class'
require 'Player'
require 'Enemies'
PLAYER_SPEED = 150
BULLET_SPEED = 250
createEnemyTimerMax = 0.4
createEnemyTimer = createEnemyTimerMax
isAlive = true
score = 0
-- called when game starts
-- load images, sounds of the game here
function love.load(arg)
gamestate = 'play'
background = love.graphics.newImage('gfx/milkyway.png')
-- initialize player
player = Player(200, 710)
-- initialize bullet
-- render image to map
bulletimage = love.graphics.newImage('gfx/bullet.png')
-- Entity storage
bullets = {} -- array of current bullets being drawn and updated
enemy = Enemies(math.random(10, 200), math.random(10, 200))
end
function love.update(dt)
-- keypress for shooting
love.keyboard.keysPressed = {}
love.keyboard.keysReleased = {}
-- move the player
if love.keyboard.isDown('left', 'a') then
if player.x > 0 then
player.x = player.x - (PLAYER_SPEED * dt)
end
elseif love.keyboard.isDown('right', 'd') then
if player.x < (love.graphics.getWidth() - player.img:getWidth()) then
player.x = player.x + (PLAYER_SPEED * dt)
end
elseif love.keyboard.isDown('up', 'w') then
if player.y > 0 then
player.y = player.y - (PLAYER_SPEED * dt)
end
elseif love.keyboard.isDown('down', 's') then
if player.y < (love.graphics.getHeight() - player.img:getHeight()) then
player.y = player.y + (PLAYER_SPEED * dt)
end
end
-- reset the game
if gamestate == 'done' and love.keyboard.isDown('r') then
gamestate = 'play'
-- remove all the bullets and enemies from the screen
bullets = {}
enemies = {}
-- reset timers
createEnemyTimer = createEnemyTimerMax
-- move player to default position
player.x = 200
player.y = 710
-- reset gamestate
score = 0
isAlive = true
end
-- keep updating the positions of bullets when shooting
for i, bullet in ipairs(bullets) do
bullet.y = bullet.y - (BULLET_SPEED * dt)
-- remove bullets when they pass off the screen
if bullet.y < 0 then
table.remove(bullets, i)
end
end
Player:update()
Enemies:update(dt)
end
-- global key pressed function
function love.keyboard.wasPressed(key)
if (love.keyboard.keysPressed[key]) then
return true
else
return false
end
end
-- global key released function
function love.keyboard.wasReleased(key)
if (love.keyboard.keysReleased[key]) then
return true
else
return false
end
end
-- called whenever a key is released
function love.keyreleased(key)
love.keyboard.keysReleased[key] = true
end
-- called whenever a key is pressed
function love.keypressed(key)
dt = love.timer.getDelta()
-- to exit the game
if love.keyboard.isDown('escape') then
love.event.quit()
end
-- create bullets when shooting
if love.keyboard.isDown('space') then
newBullet = {x = player.x + (player.img:getWidth() / 2),
y = player.y, img = bulletimage}
table.insert(bullets, newBullet)
end
love.keyboard.keysPressed[key] = true
end
function love.draw(dt)
-- set background image
love.graphics.clear(51/255, 43/255, 68/255, 1)
drawBackground()
-- draw player
if gamestate == 'play' then
player:render()
elseif gamestate == 'done' then
love.graphics.print("Press 'R' to restart", WIDTH / 2 - 50, HEIGHT / 2 - 10)
end
love.graphics.setDefaultFilter('nearest', 'nearest')
-- draw bullets
for i, bullet in ipairs(bullets) do
love.graphics.draw(bulletimage, bullet.x, bullet.y, 3)
end
-- draw enemies
enemy:render()
end
-- background is distributed for free on pixelstalk.net
function drawBackground()
for i = 0, love.graphics.getWidth() / background:getWidth() do
for j = 0, love.graphics.getHeight() / background:getHeight() do
love.graphics.draw(background, i * background:getWidth(), j * background:getHeight())
end
end
end
Enemies.lua
Enemies = Class{}
function Enemies:init(x, y)
self.x = x
self.y = y
enemies = {} -- array of current enemies on the screen
-- render image to map
self.enemyimg = love.graphics.newImage('gfx/enemy.png')
self.width = self.enemyimg:getWidth()
self.height = self.enemyimg:getHeight()
end
function Enemies:update(dt)
createEnemyTimer = createEnemyTimer - (1 * dt)
if createEnemyTimer < 0 then
createEnemyTimer = createEnemyTimerMax
-- create an enemy
randomNumber = math.random(10, love.graphics.getWidth() - 10)
newEnemy = { x = randomNumber, y = -10, img = self.enemyimg}
table.insert(enemies, newEnemy)
end
-- keep updating the positions of enemies
for i, enemy in ipairs(enemies) do
enemy.y = enemy.y + (200 * dt)
-- remove enemies when they pass off the screen
if enemy.y > 850 then
table.remove(enemies, i)
end
end
-- run our collision detection
-- also we need to see if enemies hit our player
while gamestate == 'play' do
for i, enemy in ipairs(enemies) do
for j, bullet in ipairs(bullets) do
if CheckCollision(self.x, self.y, self.width, self.height,
bullet.x, bullet.y, bullet.bulletimage:getWidth(), bullet.bulletimage:getHeight()) then
table.remove(bullets, j)
table.remove(enemies, i)
score = score + 1
end
end
if CheckCollision(self.x, self.y, self.width, self.height,
player.x, player.y, player.width, player.height)
and isAlive == true then
table.remove(enemies, i)
isAlive = false
gamestate = 'done'
end
end
end
end
function Enemies:render()
-- pixel aircrafts created by chabull and
-- distributed for free on OpenGameArt.org
for i, enemy in ipairs(enemies) do
love.graphics.draw(self.enemyimg, self.x, self.y)
end
end
-- function to check collision
-- returns true if 2 objects overlap, false if they don't
-- x1, y1 are left-top coords of the first object, while w1, h1 are its width and height
-- x2, y2, w2, h2 are the same, but for the second object
function CheckCollision(x1, y1, w1, h1, x2, y2, w2, h2)
if x1 < x2 + w2 and x2 < x1 + w1 and y1 < y2 + h2 and y2 < y1 + h1 then
return true
else
return false
end
end
我不是Love2d专家,但Enemies.update可能被称为每一帧。对我来说,在条件为gamestate == 'play'
的情况下始终运行该条件的情况下运行while循环对我来说似乎是有问题的。
您基本上陷入了无限循环,而不是更新游戏状态。