lua solar2d. player passes through obstacles and incorrect transition to another level

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

New contributor

Arikase is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.

Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa Dịch vụ tổ chức sự kiện 5 sao Thông tin về chúng tôi Dịch vụ sinh nhật bé trai Dịch vụ sinh nhật bé gái Sự kiện trọn gói Các tiết mục giải trí Dịch vụ bổ trợ Tiệc cưới sang trọng Dịch vụ khai trương Tư vấn tổ chức sự kiện Hình ảnh sự kiện Cập nhật tin tức Liên hệ ngay Thuê chú hề chuyên nghiệp Tiệc tất niên cho công ty Trang trí tiệc cuối năm Tiệc tất niên độc đáo Sinh nhật bé Hải Đăng Sinh nhật đáng yêu bé Khánh Vân Sinh nhật sang trọng Bích Ngân Tiệc sinh nhật bé Thanh Trang Dịch vụ ông già Noel Xiếc thú vui nhộn Biểu diễn xiếc quay đĩa Dịch vụ tổ chức tiệc uy tín Khám phá dịch vụ của chúng tôi Tiệc sinh nhật cho bé trai Trang trí tiệc cho bé gái Gói sự kiện chuyên nghiệp Chương trình giải trí hấp dẫn Dịch vụ hỗ trợ sự kiện Trang trí tiệc cưới đẹp Khởi đầu thành công với khai trương Chuyên gia tư vấn sự kiện Xem ảnh các sự kiện đẹp Tin mới về sự kiện Kết nối với đội ngũ chuyên gia Chú hề vui nhộn cho tiệc sinh nhật Ý tưởng tiệc cuối năm Tất niên độc đáo Trang trí tiệc hiện đại Tổ chức sinh nhật cho Hải Đăng Sinh nhật độc quyền Khánh Vân Phong cách tiệc Bích Ngân Trang trí tiệc bé Thanh Trang Thuê dịch vụ ông già Noel chuyên nghiệp Xem xiếc khỉ đặc sắc Xiếc quay đĩa thú vị
Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa
Thiết kế website Thiết kế website Thiết kế website Cách kháng tài khoản quảng cáo Mua bán Fanpage Facebook Dịch vụ SEO Tổ chức sinh nhật