这篇继续上篇,分为两部分,一游戏背景、玩家和敌机的显示,
二子弹发射和计分。(注:一些全局变量放在了conf.lua里)
一、游戏背景、玩家和敌机的显示
这个游戏的背景用的是一个32*32的图片,怎么才能让其在整个屏幕上显示呢?其实只需要加载
图片后,用for循环让其在不同的坐标处显示即可,代码如下:
-- 绘制动态的背景 for i = 0,4 do --绘制5列 for j = -1,4 do --绘制6行 --绘制坐标随时间变化,y坐标增大32*scale,这里32为图片的宽和高 love.graphics.draw(imgs["background"], i*32*scale, (j+game.clock%1)*32*scale, 0,scale,scale) end end
玩家的绘制和控制比较简单,只需加载图片,在update里检测按键,更新坐标就可以,不再敖述。
敌机的显示则相对复杂了,这个游戏只使用了一副敌机图片,作者巧妙的用随机数生成敌机坐标表,
遍历坐标表绘制敌机。另外一个便是一般的飞行射击游戏,越到后敌机越多,这个又怎么实现呢?
作者设定了一个敌机产生时间间隔,之后没到间隔时间便减少此间隔,这样敌机便产生的越来越快。
代码如下:
-- 敌机计时 game.enemy_dt = game.enemy_dt + dt -- 随机产生大量敌机的坐标 if game.enemy_dt > game.enemy_rate then game.enemy_dt = game.enemy_dt - game.enemy_rate game.enemy_rate = game.enemy_rate - 0.01 * game.enemy_rate --缩短产生敌机的时间间隔,即敌机产生的越来越快 local enemy = {} enemy.x = math.random((8)*scale,(160-8)*scale) enemy.y = -game.enemy_size --负号表示产生后在y小于0 table.insert(game.enemies,enemy) end -- 更新敌机的坐标 for ei,ev in ipairs(game.enemies) do ev.y = ev.y + 70*dt*scale if ev.y > 144*scale then table.remove(game.enemies,ei) endend
以上完整代码,点击。
二、子弹发射和计分
子弹可以分为两种,即发射的子弹和没发射的子弹。首先,我们设定子弹的总个数,没按一次
发射键(空格),我们便想发射的子弹里添加它,并把没发射的子弹个数减一。之后在update
里更新子弹的坐标,还有要注意子弹与敌机的碰撞,如果子弹击中敌机要把子弹和敌机都移除。
子弹另一个注意点是弹药补充,我们可以设置一个更新间隔,每次达到这个间隔便把子弹个数
加一。代码如下:
-- 子弹初始化代码 game.ammo = 10 --子弹个数 game.recharge_dt = 0 --子弹恢复计时 game.recharge_rate = 1 --子弹恢复间隔 game.bullet_size = imgs["bullet"]:getWidth() game.bullets = {} --运动的子弹表 shoot = love.audio.newSource( "assets/shoot.mp3" , "static" ) --子弹射击声--子弹绘制代码-- 绘制运动的子弹 for _,v in ipairs(game.bullets) do love.graphics.draw(imgs["bullet"], v.x,v.y, 0,scale,scale, game.bullet_size/2,game.bullet_size/2) if debug then love.graphics.circle("line",v.x,v.y,game.bullet_size/2*scale) end end--子弹更新代码 -- 子弹更新 for bi,bv in ipairs(game.bullets) do bv.y = bv.y - 100*dt*scale --子弹向上,故减 if bv.y < 0 then table.remove(game.bullets,bi) --超出屏幕移除 end -- 如果子弹打中敌机移除敌机和子弹 for ei,ev in ipairs(game.enemies) do if game.dist(bv.x,bv.y,ev.x,ev.y) < (2+8)*scale then game.score = game.score + 1 table.remove(game.enemies,ei) table.remove(game.bullets,bi) end end end -- 更新玩家弹药信息 game.recharge_dt = game.recharge_dt + dt if game.recharge_dt > game.recharge_rate then game.recharge_dt = game.recharge_dt - game.recharge_rate game.ammo = game.ammo + 1 if game.ammo > 10 then game.ammo = 10 end end
至于计分,打中敌机后分数加一即可,完整代码下载。
这里有几点需要注意一下,一是本篇的splash和上篇的splash想比,有少许改动,
主要是把state改为全局变量,load函数参数也改了;二是要注意玩家死后状态的切换,可以
在game.lua和splash.lua里搜索state即可;三是我默认把debug设为了true,按tab键上
面的"`"可以关闭或打开。其实这个游戏还有提高之处,例如让敌机也可以发射子弹,增加
敌机和子弹的种类等,大家可以发挥自己的想象力。如果你做出了更好的游戏,欢迎发给我
(在评论里贴上下载地址即可),如果遇到了问题,也欢迎发给我,我会在48小时内答复。