It looks like you're new here. If you want to get involved, click one of these buttons!
local sound = Sound.new("MakoBeamNCSGiderosCompRemix(-32Db).wav") local channel = sound:play() application:setFps(60) hiScore= 0 score = 0 layerstartDir = "LTR" --(Left to right) This defines which way the layer is going to start off moving Pool = Core.class(bullet) function Pool:init() self.pool = {} end function Pool:createObject() local b if #self.pool > 0 then b = table.remove(self.pool) else b = Bitmap.new(Texture.new("bullet.png", true)) b:setScale(0.2) b:setPosition(0,0) b:setRotation(-90) end return b end function Pool:destroyObject(b) b:removeFromParent() table.insert(self.pool, b) end bullets = {} counter = 1 application:setBackgroundColor(0x0) width = application:getContentWidth() local username = "" local textInputDialog = TextInputDialog.new("Player1", "Enter Name Player1", username, "Cancel", "Save") backgroundtexture = Texture.new("BGComp.png") backgroundtexture = Bitmap.new(backgroundtexture) stage:addChild(backgroundtexture) backgroundtexture:setAnchorPoint(0.5,0.5) backgroundtexture:setRotation(90) backgroundtexture:setPosition(239,160) backgroundtexture:setScaleX(1.75) backgroundtexture:setScaleY(1.75) local retrofont = TTFont.new("8-BIT WONDER.TTF", 20, true) local text = TextField.new(retrofont,username) text:setPosition(0, 20) stage:addChild(text) text:setTextColor(0xffffff) stage:addEventListener(Event.ENTER_FRAME, function() text:setTextColor(text:getTextColor()+3) end) local rec = Shape.new() rec:setFillStyle(Shape.SOLID, 0xffffffff, 0.3) rec:setLineStyle(3, 0x00000, 1) rec:beginPath() rec:moveTo(0,0) rec:lineTo(0,100) rec:lineTo(200,100) rec:lineTo(200,0) rec:lineTo(0,0) rec:endPath() stage:addChild(rec) rec:setPosition(-10, 224) rec:setScaleX(3) local firetext = TextField.new(retrofont,"fire") stage:addChild(firetext) firetext:setPosition(397,310) firetext:setTextColor(0x00000) if score > hiScore then hiScore = score end scoreText = TextField.new(retrofont, "Score: " .. score) scoreText:setPosition(4,290) stage:addChild(scoreText) hiScoreText = TextField.new(retrofont, "Hi-Score: " .. hiScore) hiScoreText:setPosition(4,270) stage:addChild(hiScoreText) firebutton = Bitmap.new(Texture.new("Button.png")) stage:addChild(firebutton) firebutton:setScale(0.6) firebutton:setAnchorPoint(0.5,0.5) firebutton:setPosition(430,260) playership1 = Bitmap.new(Texture.new("ship.png")) stage:addChild(playership1) playership1:setAnchorPoint(0.39,0.39) playership1:setPosition(200,260) function firebutton:onClick(e) if self:hitTestPoint(e.x, e.y) then self:setScale(0.5) end end function firebutton:onRelease(e) if self:hitTestPoint(e.x, e.y) then self:setScale(0.6) end end firebutton:addEventListener(Event.MOUSE_DOWN, firebutton.onClick, firebutton) firebutton:addEventListener(Event.MOUSE_UP, firebutton.onRelease, firebutton) local function onComplete(e) --if e.buttonIndex then username = e.text text:setText(username) --end end textInputDialog:addEventListener(Event.COMPLETE, onComplete) textInputDialog:show() left = false right = false shipX=width/2 playerDir=0 bDir=0 by= 1 bullets = {} counter = 1 bpool = Pool.new() function gameloop(e) local layerX = invadersLayer:getX() --This finds the actual position of the layer if layerstartDir == "LTR" and layerX<= 70 then invadersLayer:setX(layerX+1.5) -- where 1 is the pixel speed at which layer moves Left to right else --we reached the limit, change direction layerstartDir = "RTL" --right to left end if layerstartDir == "RTL" and layerX>= -40 then -- -50 is my choice, it's the x position where layer direction should reverse at the left of the screen when moving RTL invadersLayer:setX(layerX-1.5) -- same as before, but negative else --do... layerstartDir = "LTR" -- (left to right again) end shipX=shipX + (playerDir* 5) if shipX<14 then shipX = 14 elseif shipX>(width-55) then shipX = width - w end playership1:setX(shipX) --you need to update the position of each bullet in bullets array for bb in pairs(bullets) do --for any entry of bullets, where bb is index local bp = bullets[bb]:getY() --bulletPosition: each bullet has its own if bp < -100 then --this is what I decided is enough outside screen boundaries to remove the bullet (in pixels, same scale as setX, setY...) bpool:destroyObject(bullets[bb]) --place bullet in pool bullets[bb] = nil --remove entry from array so that next time it won't be processed print("bullets removed:", bb) --tell me that you did it else --I am still inside the screen, so: local by=bp+(bDir*8) --add the increment to this bullet bp bullets[bb]:setY(by) --set the increment to this bullet end end end stage:addEventListener(Event.ENTER_FRAME,gameloop) stage:addEventListener(Event.KEY_DOWN,function(e) if e.keyCode==KeyCode.LEFT then left=true playerDir=-1 elseif e.keyCode==KeyCode.RIGHT then right=true playerDir=1 elseif e.keyCode==KeyCode.Z then print("fire") bx,by=playership1:getPosition() bullets[counter] = bpool:createObject() stage:addChild(bullets[counter]) bullets[counter]:setPosition(bx,by) bDir=-1 counter = counter+1 end end) stage:addEventListener(Event.KEY_UP,function(e) if e.keyCode==KeyCode.LEFT then left=false if right then playerDir=1 else playerDir=0 end elseif e.keyCode==KeyCode.RIGHT then right=false if left then playerDir=-1 else playerDir=0 end end end) Invader = Core.class(Sprite) function Invader:init() local anim1 = {} anim1[1] = Bitmap.new(Texture.new("invader2.png")) anim1[2] = Bitmap.new(Texture.new("invader.png")) local anim1 = MovieClip.new{ {1,20, anim1[1]}, {20,40, anim1[2]}, anim1[1]:setScale(0.3) } anim1:setPosition(0,-5) self:addChild(anim1) anim1:setGotoAction(40, 1) anim1:gotoAndPlay(1) end local maxInvaders = 10 local invaders = {} invadersLayer = Sprite.new() stage:addChild(invadersLayer) local paddx = 75 for i=1, maxInvaders do invaders[i] = Invader.new() invaders[i]:setX(paddx*i) invadersLayer:addChild(invaders[i]) invadersLayer:setScale(0.5) invadersLayer:setPosition(0 ,25) end |
Comments
The first that comes to mind is to use a for loop and Sprite:collidesWith() by ar2rsawseen.
copy the function at the beginning of your file: it adds collidesWith() as a method of Sprite.
Since collidesWith is a method of Sprite, you would need that your bullets were Sprites too (now these are Bitmaps, while Invaders already are Sprites): you need to add the bitmap to a Sprite instance for this to work.
then you could insert another for in the for loop updating the bullets position:
function Sprite:collidesWith(sprite2) -- goes at the beginning of your file
--excerpt of Pool:createObject() goes in Pool:createObject()
it's an update to existing code: where you had b = blah blah, now you have local c = blah blah, and then b = Sprite.new and b:addChild(c)
--the last piece goes inside gameloop(), it's an update to the "bullet movement for loop": the added for loop is at the end and not aligned with previous code.
main.lua:216: attempt to index field '?' (a nil value)
stack traceback:
main.lua:216: in function
I've checked the area no typos as far as I'm aware everything seems normal.
function 202 is:
;D
https://deluxepixel.com
Move the loop that checks for a bullet hitting an invader to the bit that increments the position of the bullet.
Likes: pie
https://deluxepixel.com
Thanks for your time.
I personally would add score after all the objects have been added - so it's drawn on top.
To set the score every game frame add:
Then in your gameloop event...
https://deluxepixel.com