require "Common" require "LayerScrollBackground" function SceneGame(idx) --创建 local scene = cc.Scene:create() local winSize = cc.Director:getInstance():getWinSize() -- 滚动的背景 local bgLayer = LayerScrollBackground() -- 场景中加上层 scene:addChild(bgLayer) -- 数据结构,子弹的数组和敌机的数组 local bullets = {} -- 添加敌机 local enemys = {} -- 创建英雄战机 local plane = cc.Sprite:create("Player" .. idx .. ".png") -- 场景中添加飞机 scene:addChild(plane) -- 设置飞机的位置 plane:setPosition(winSize.width/2,plane:getBoundingBox().height) -- 设置plane的ZOrder plane:setLocalZOrder(100) ----- 加载战斗机的属性 local vm = cc.FileUtils:getInstance():getValueMapFromFile("planeinfo.xml"); plane.damage = tonumber(vm["planedamageamount" .. idx]) plane.hp = tonumber(vm["plane" .. idx .. "_hp"]) plane.cd = tonumber(vm["planeshootspeedrate" .. idx]) plane.curCD = 0; cclog(plane.damage .. " " .. plane.hp .. " " .. plane.cd) -- 显示分数和血的Label local labelScore = nil local labelHP = nil local function createLabels() -- 设置label labelHP = cc.Label:createWithSystemFont("" .. plane.hp,"Arial",50) -- 设置Label的锚点 labelHP:setAnchorPoint(cc.p(1,1)) -- 设置锚点的位置 labelHP:setPosition(winSize.width,winSize.height) scene:addChild(labelHP) labelHP:setLocalZOrder(1010) labelScore = cc.Label:createWithSystemFont("0",50) labelScore:setAnchorPoint(cc.p(0,1)) labelScore:setPosition(0,winSize.height) scene:addChild(labelScore) labelScore:setLocalZOrder(1010) end createLabels() -- 移动飞机 -- 增加Touch处理 local function onTouchBegan(touch,event) return true end local function onTouchMoved(touch,event) local x,y = plane:getPosition() local d = touch:getDelta() plane:setPosition(x+d.x,y+d.y) end local function onTouchEnded(touch,event) end regTouch(scene,onTouchMoved) ------------------- shoot -- angle参数代表的发射角度,delta表示子弹发射的起始位置和英雄战机的位置的偏移 local function shootOne(angle,delta) cc.SimpleAudioEngine:getInstance():playEffect("m/bullet.wav") local bullet = cc.Sprite:create("Bullet.png") scene:addChild(bullet) local x,y = plane:getPosition() bullet:setPosition(x+delta.x,y+delta.y) bullet:setRotation(angle) -- math.rad(角度) 把角度转换成弧度 local dx = math.sin( math.rad(angle) ) * winSize.height local dy = math.cos( math.rad(angle) ) * winSize.height local moveBy = cc.MoveBy:create(5,cc.p(dx,dy)) bullet:runAction(moveBy) -- 子弹保存在数组里 table.insert(bullets,bullet) end local function Shoot() local sizePlane = plane:getContentSize() if idx == 1 then shootOne(0,cc.p(0,sizePlane.height/2)) elseif idx == 2 then shootOne(0,sizePlane.height/2)) shootOne(0,cc.p(-sizePlane.width/4,sizePlane.height/4)) shootOne(0,cc.p(sizePlane.width/4,sizePlane.height/4)) elseif idx == 3 then shootOne(0,sizePlane.height/2)) shootOne(-30,sizePlane.height/2)) shootOne(30,sizePlane.height/2)) elseif idx == 4 then shootOne(0,sizePlane.height/2)) shootOne(180,-sizePlane.height/2)) shootOne(90,cc.p(sizePlane.width/2,0)) shootOne(270,cc.p(-sizePlane.width/2,0)) elseif idx==5 then shootOne(45,0)) shootOne(45+90,0)) shootOne(45+180,0)) shootOne(45+270,0)) end end local function tickShoot() plane.curCD = plane.curCD + 1 if plane.curCD >= plane.cd then Shoot() plane.curCD = 0 end end local tickShootID = cc.Director:getInstance():getScheduler():scheduleScriptFunc(tickShoot,false) -- 检查子弹是否飞出窗口外 local function checkBulletAndEnemy() -- 得到子弹数量 local n = table.getn(bullets) for i = n,1,-1 do local bullet = bullets[i] -- 判断bullet是不是出了窗口 local x,y = bullet:getPosition() if x<0 or y<0 or x>winSize.width or y > winSize.height then bullet:removeFromParent() table.remove(bullets,i) -- 从bullets数组中,删除下标为i的元素 cclog("bullet is out of window") end end n = table.getn(enemys) for i = n,-1 do local enemy = enemys[i] -- 判断enemy是不是出了窗口 local x,y = enemy:getPosition() if y < -enemy:getContentSize().height/2 then enemy:removeFromParent() table.remove(enemys,i) -- 从enemys数组中,删除下标为i的元素 end end end local tickCheckBullet = cc.Director:getInstance():getScheduler():scheduleScriptFunc(checkBulletAndEnemy,false) -- 产生敌机的定时器 local function genEnemy(type) -- 创建敌机精灵,加入到数组,加入渲染树 -- 增加敌机属性 -- 随机设置位置 local enemy = cc.Sprite:create("Enemy" .. type .. ".png") table.insert(enemys,enemy) scene:addChild(enemy) -- 敌军飞机的额外属性 local hp = {10,30,100} enemy.hp = hp[type] local score = {1000,3000,10000} enemy.score = score[type] local speed = {150,100,50} enemy.speed = speed[type] enemy.type = type -- 设置初始位置 local sizePlane = enemy:getContentSize() math.randomseed(os.time()) local x = math.random(sizePlane.width/2,winSize.width-sizePlane.width/2) local y = winSize.height + sizePlane.height/2 enemy:setPosition(x,y) -- 设置飞机飞行动作 local distance = winSize.height + sizePlane.height + 5 local moveBy = cc.MoveBy:create(distance*1.0/enemy.speed,-distance)) enemy:runAction(moveBy) end local function genEnemy1() genEnemy(1) end local function genEnemy2() genEnemy(2) end local function genEnemy3() genEnemy(3) end local tickGenEnemy1 = cc.Director:getInstance():getScheduler():scheduleScriptFunc(genEnemy1,false) local tickGenEnemy2 = cc.Director:getInstance():getScheduler():scheduleScriptFunc(genEnemy2,3,false) local tickGenEnemy3 = cc.Director:getInstance():getScheduler():scheduleScriptFunc(genEnemy3,10,false) local function loadBoomAnimation() local spriteFrameCache = cc.SpriteFrameCache:getInstance() spriteFrameCache:addSpriteFrames("PFBoom.plist") -- CCArray* arr = CCArray:create() local spriteFrames = {} for i = 1,18 do local spriteFrame = spriteFrameCache:getSpriteFrame("Boom_" .. i .. ".png") table.insert(spriteFrames,spriteFrame) end local animation = cc.Animation:createWithSpriteFrames(spriteFrames,0.05) cc.AnimationCache:getInstance():addAnimation(animation,"ENEMYBOOM") end loadBoomAnimation() local function removeEnemy(node,tab) node:removeFromParent() end local function enemyBoom(idx) local enemy = enemys[idx] cc.SimpleAudioEngine:getInstance():playEffect("m/enemy" .. enemy.type .. "_down.wav") -- 增加分数 local score = labelScore:getString() score = tonumber(score) + enemy.score labelScore:setString("" .. score) table.remove(enemys,idx) -- 执行爆炸动画,然后再调用removeFromParent local animation = cc.AnimationCache:getInstance():getAnimation("ENEMYBOOM") local animate = cc.Animate:create(animation) local callfunc = cc.CallFunc:create(removeEnemy) local seq = cc.Sequence:create(animate,callfunc) enemy:runAction(seq) -- enemy:removeFromParent() end local function collision() local nEnemy = table.getn(enemys) local rcPlane = plane:getBoundingBox() for i = nEnemy,-1 do local enemy = enemys[i] local rcEnemy = enemy:getBoundingBox() local bEnemyBoom = false -- 如果敌机和英雄战机碰撞,rcEnemy,rcPlane if cc.rectIntersectsRect(rcEnemy,rcPlane) then plane.hp = plane.hp - enemy.hp labelHP:setString("" .. plane.hp) if plane.hp <= 0 then cc.Director:getInstance():replaceScene(SceneMenu()) break end enemyBoom(i) bEnemyBoom = true end -- 跟子弹进行碰撞检测 if bEnemyBoom == false then local nBullet = table.getn(bullets) for j = nBullet,-1 do local bullet = bullets[j] -- 如果子弹和敌机碰撞 local ptBullet = cc.p( bullet:getPosition() ) if cc.rectContainsPoint(rcEnemy,ptBullet) then bullet:removeFromParent() table.remove(bullets,j) enemy.hp = enemy.hp - plane.damage; if enemy.hp <= 0 then enemyBoom(i) break -- 表示这个敌机不再和下一个子弹做碰撞检测 end end end end end end local tickCollisionID = cc.Director:getInstance():getScheduler():scheduleScriptFunc(collision,false) local function Back() cc.Director:getInstance():replaceScene(SceneMenu()) end createBackMenu(scene,Back) -- 注销定时器 local function onNodeEvent(event) if "enter" == event then cclog("OnEnter") cc.SimpleAudioEngine:getInstance():playMusic("m/game_music.wav",true) end if "exit" == event then cc.SimpleAudioEngine:getInstance():stopMusic() cc.Director:getInstance():getScheduler():unscheduleScriptEntry(tickShootID) cc.Director:getInstance():getScheduler():unscheduleScriptEntry(tickCheckBullet) cc.Director:getInstance():getScheduler():unscheduleScriptEntry(tickGenEnemy1) cc.Director:getInstance():getScheduler():unscheduleScriptEntry(tickGenEnemy2) cc.Director:getInstance():getScheduler():unscheduleScriptEntry(tickGenEnemy3) cc.Director:getInstance():getScheduler():unscheduleScriptEntry(tickCollisionID) end end scene:registerScriptHandler(onNodeEvent) return scene end |