Reputation: 1
lua solar2d. I have a player and obstacles, I grouped the hitbox and texture to move together, but then the event of collision between the player and the obstacle is not processed, without the group and following textures everything works, as well as when moving to another level, instead of waiting for a click from the player, the game works, although at the start of the 1st level waiting correctly.
have no other ideas.
local composer = require("composer")
local scene = composer.newScene()
local physics = require("physics")
physics.start()
local background = display.newRect(320, 240, 1000, 1000)
background:setFillColor(0.8, 0.8, 0.8, 1)
local ground = display.newRect(200, 300, 1000, 40)
ground:setFillColor(1, 1, 1, 1)
physics.addBody(ground, "static")
local startScreen = display.newGroup()
local startText = display.newText("Нажмите, чтобы начать!", 250, 150, "Helvetica", 25)
startText:setFillColor(0.2, 0.2, 0.2, 1)
startScreen:insert(startText)
local score = 0
local currentScore = display.newText(score, -70, 20, "Helvetica", 25)
local scoreText = display.newText("m / 200 m", 50, 20, "Helvetica", 25)
scoreText:setFillColor(0.4, 0.4, 0.4, 1)
currentScore:setFillColor(0.4, 0.4, 0.4, 1)
local startX = 50
local startY = 250
local player = display.newRect(startX, startY, 20, 60)
player:setFillColor(0.4, 0.4, 0.4, 0)
physics.addBody(player, "dynamic")
player.isJumping = false
player.isDucking = false
player.duckingCooldown = false
player.shootingCooldown = false
player.gravityScale = 0
player.isAlive = true
local sheetChar =
{
width = 300,
height = 300,
numFrames = 7
}
local imageSheet = graphics.newImageSheet("dino_sprite_sheet.png", sheetChar)
local sequenceData =
{
{ name = "run", start = 1, count = 4, time = 600, loopCount = 0, loopDirection = "forward" },
{ name = "death", start = 5, count = 1, time = 1000, loopCount = 1 },
{ name = "duck", start = 6, count = 2, time = 600, loopCount = 0, loopDirection = "forward" },
{ name = "jump", start = 1, count = 1, time = 600, loopCount = 1 }
}
local character = display.newSprite(imageSheet, sequenceData)
character:scale(0.2, 0.2)
local function OnCollision(event)
if event.phase == "began" and event.other == ground then
player.isJumping = false
end
end
local function Crash1(self, event)
if (event.phase == "began" and (event.other.ID == "obstacle_t1" or
event.other.ID == "obstacle_t3" or event.other.ID == "obstacle_t4" or
event.other.ID == "obstacle_t2" and not player.isDucking)) then
print("+")
player.isAlive = false
transition.cancel()
player:setLinearVelocity(0, 0)
end
end
player.collision = Crash1
player:addEventListener("collision", player)
player:addEventListener("collision", OnCollision)
local function Crash2(self, event)
if event.phase == "began" then
if event.other.ID == "obstacle_t4" then
if self.removeSelf then
self:removeSelf()
end
if event.other and event.other.removeSelf then
event.other:removeSelf()
end
elseif event.other.ID == "obstacle_t1" or event.other.ID == "obstacle_t2" or event.other.ID == "obstacle_t3" then
if self.removeSelf then
self:removeSelf()
end
end
end
end
local function Jump(event)
if player.isAlive then
if event.phase == "began" and not player.isJumping and not player.isDucking then
player.isJumping = true
if character.sequence ~= "jump" then
character:setSequence("jump")
character:play("jump")
end
transition.to(player, {time=400, y=startY - 100, transition=easing.outQuad, onComplete=function()
transition.to(player, {time=400, y=startY, transition=easing.inQuad})
end})
if character.sequence ~= "run" then
character:setSequence("run")
character:play("run")
end
end
end
end
local function Duck(event)
if player.isAlive then
if event.phase == "began" and not player.isJumping and not player.isDucking
and not player.duckingCooldown then
player.duckingCooldown = true
player.isDucking = true
if character.sequence ~= "duck" then
character:setSequence("duck")
character:play("duck")
end
timer.performWithDelay(1200, function()
player.duckingCooldown = false
player.isDucking = false
if not player.isJumping and character.sequence ~= "run" then
character:setSequence("run")
character:play("run")
end
end)
end
end
end
local function Shoot(event)
if event.phase == "began" and player.isAlive and not player.isJumping and not player.isDucking and not player.shootingCooldown then
player.shootingCooldown = true
local bullet = display.newCircle(player.x + 20, player.y, 5)
bullet:setFillColor(1, 1, 1, 1)
physics.addBody(bullet, "dynamic")
bullet.gravityScale = 0
bullet.isBullet = true
bullet.ID = "bullet"
bullet.isAlive = true
bullet.collision = Crash2
bullet:addEventListener( "collision", bullet )
transition.to(bullet, {
time = 500,
x = player.x + 100,
onComplete = function()
if bullet and bullet.removeSelf then
bullet:removeSelf()
end
end
})
timer.performWithDelay(2500, function() player.shootingCooldown = false end)
end
end
local obstacleSpawnInterval = 3000
local obstacleSpeed = 4000
local sheetKakt =
{
width = 300,
height = 300,
numFrames = 5
}
local imageSheet2 = graphics.newImageSheet("kaktus_sprite_sheet.png", sheetKakt)
local sequenceData2 =
{
{ name = "kakt1", start = 1, count = 1, time = 1000, loopCount = 1 },
{ name = "kakt2", start = 2, count = 1, time = 1000, loopCount = 1 },
{ name = "kakt3", start = 3, count = 1, time = 1000, loopCount = 1 },
{ name = "kakt4", start = 4, count = 2, time = 400, loopCount = 0, loopDirection = "forward" }
}
local function SpawnObstacle()
if player.isAlive then
local obstacleGroup = display.newGroup()
local obstacle = display.newRect(0, 0, 40, 60)
local charObstacle
local obstacleType = math.random(1, 4)
-- Птица
if obstacleType == 1 then
obstacle.height, obstacle.width = 20, 60
obstacle.y = -25
charObstacle = display.newSprite(imageSheet2, sequenceData2)
charObstacle:setSequence("kakt4")
charObstacle:scale(0.25, 0.25)
obstacle.ID = "obstacle_t2"
-- базовый кактус
elseif obstacleType == 2 then
obstacle.height, obstacle.width = 60, 40
obstacle.y = 0
charObstacle = display.newSprite(imageSheet2, sequenceData2)
charObstacle:setSequence("kakt1")
charObstacle:scale(0.25, 0.25)
obstacle.ID = "obstacle_t1"
-- Поле кактусов
elseif obstacleType == 3 then
obstacle.height, obstacle.width = 40, 75
obstacle.y = 10
charObstacle = display.newSprite(imageSheet2, sequenceData2)
charObstacle:setSequence("kakt2")
charObstacle:scale(0.35, 0.35)
obstacle.ID = "obstacle_t3"
-- Длинный кактус
else
obstacle.height, obstacle.width = 100, 40
obstacle.y = -10
charObstacle = display.newSprite(imageSheet2, sequenceData2)
charObstacle:setSequence("kakt3")
charObstacle:scale(0.5, 0.5)
obstacle.ID = "obstacle_t4"
end
obstacle:setFillColor(0.3, 0.3, 0.3, 0.8)
physics.addBody(obstacle, "dynamic")
obstacle.gravityScale = 0
obstacle.isSensor = true
if charObstacle then
charObstacle:play()
obstacleGroup:insert(charObstacle)
end
obstacleGroup:insert(obstacle)
obstacleGroup.x = 600
obstacleGroup.y = 250
transition.to(obstacleGroup, {time = obstacleSpeed, x = -150, onComplete = function()
if obstacle and obstacle.removeSelf then
obstacleGroup:removeSelf()
end
end})
end
end
local jumpButton = display.newRect(-50, 300, 40, 30)
jumpButton:addEventListener("touch", Jump)
jumpButton:setFillColor(0, 0, 0, 0.01)
local duckButton = display.newRect(20, 300, 40, 30)
duckButton:addEventListener("touch", Duck)
duckButton:setFillColor(0, 0, 0, 0.01)
local shootButton = display.newRect(90, 300, 40, 30)
shootButton:addEventListener("touch", Shoot)
shootButton:setFillColor(0, 0, 0, 0.01)
local sheetChar3 =
{
width = 300,
height = 300,
numFrames = 3
}
local imageSheet3 = graphics.newImageSheet("button_sprite_sheet.png", sheetChar3)
local sequenceData3 =
{
{ name = "b1", start = 1, count = 1, time = 1000, loopCount = 1 },
{ name = "b2", start = 2, count = 1, time = 1000, loopCount = 1 },
{ name = "b3", start = 3, count = 1, time = 1000, loopCount = 1 }
}
local p = 140
for i = 1, 3 do
local charButton = display.newSprite(imageSheet3, sequenceData3)
charButton:setSequence("b" .. i)
charButton:scale(0.1, 0.1)
charButton.x = -120 + i * p / 2
charButton.y = 300
charButton:play()
end
local function UpdateScore()
if player.isAlive and score <= 200 then
score = score + 1
currentScore.text = score
end
end
local function startGame(event)
if event.phase == "ended" then
display.remove(startScreen)
UpdateScore()
character:play("run")
timer.performWithDelay(obstacleSpawnInterval, SpawnObstacle, 0)
timer.performWithDelay(50, UpdateScore, 0)
end
end
startScreen:addEventListener("touch", startGame)
local isEnd = false
local function Update()
if not isEnd then
if score == 200 then
local textWin = display.newText("Вы победили!", 250, 150, "Helvetica", 25)
textWin:setFillColor(0.2, 0.2, 0.2, 1)
transition.cancel()
timer.performWithDelay(2000, function()
display.remove(textWin)
composer.gotoScene("level2")
end)
end
character.x, character.y = player.x, player.y
if not player.isAlive then
if character.sequence ~= "death" then
character:setSequence("death")
character:play("death")
local textLose = display.newText("Вы проиграли!", 250, 150, "Helvetica", 25)
textLose:setFillColor(0.2, 0.2, 0.2, 1)
isEnd = true
transition.cancel()
timer.cancel(scoreTimer)
timer.cancel(obstacleTimer)
removeListeners()
end
elseif player.isDucking then
if character.sequence ~= "duck" then
character:setSequence("duck")
character:play("duck")
end
elseif player.isJumping then
if character.sequence ~= "jump" then
character:setSequence("jump")
character:play("jump")
end
elseif character.sequence ~= "run" then
character:setSequence("run")
character:play("run")
end
end
end
Runtime:addEventListener("enterFrame", Update)
return scene
Upvotes: 0
Views: 20