在Lua中消失精灵

如何解决在Lua中消失精灵

Lua和Love2D的新功能在这里!我正在尝试完成我正在参加的此在线课程的最终项目,我想知道如何使精灵消失。目前,我拥有这样一个功能,即播放器属于一类,而与地图有关的任何内容(即图块和背景)都属于另一类。我要写的是,如果玩家击中一个特定的方块,则该方块消失,计数器增加。我知道关于带球的cs50 gamedev课程也存在类似的问题,但是我不太了解其中的代码,所以我希望有人可以帮助我。我的map.lua看起来像这样:

require 'Util'
require 'Player'

Map = Class{}

-- Storing where all the sprites are in the tile spritesheet
EMPTY = 1
LID = 2
SUSHI1 = 3
SUSHI2 = 4

-- Storing where the background should be
BACKGROUND = 1

-- Scroll speed for the camera
local SCROLL_SPEED = 200

function Map:init()

    -- Storing the spritesheet
    self.background = love.graphics.newImage('Graphics/platform/NEW/back2.png')
    self.spritesheet = love.graphics.newImage('Graphics/platform/newplatforms/all.png')

    -- Storing the width and height of each sprite AND background width and height
    self.backgroundWidth = 500
    self.backgroundHeight = 2000
    self.tileWidth = 35
    self.tileHeight = 15

    -- Creating a player object so that it has access to the map properties
    -- Passing in the self object for that specific reason
    self.player = Player(self)

    -- Table to contain all the tile sprites
    self.tiles = {}
    -- Table to contain all the background sprites
    self.back = {}

    -- Stores the map width and height
    -- NOTE that these values are chosen through experimentation
    self.mapWidth = 15
    self.mapHeight = 133

    -- Cutting the sprites of the sheet AND background
    self.backgroundSprites = generateQuads(self.background,self.backgroundWidth,self.backgroundHeight)
    self.tileSprites = generateQuads(self.spritesheet,self.tileWidth,self.tileHeight)

    -- Setting the camera values
    self.camX = 0
    self.camY = self.backgroundHeight - VIRTUAL_HEIGHT

    -- Setting the background tiles
    for y = 1,self.mapHeight do
        for x = 1,self.mapWidth do
            self:setTileBackground(x,y,BACKGROUND)
        end
    end

    -- Setting all the tiles initially to be empty
    for y = 1,self.mapWidth do
            self:setTile(x,EMPTY)
        end
    end

    -- Setting the initial floor
    for x = 1,self.mapWidth do
        self:setTile(x,self.mapHeight,LID)
    end

    ------------------------------------------------- START OF MAP CREATION -------------------------------------------------
    local y = 1
    -- variable to help with the twist
    local location = 5
    while y < self.mapHeight do
        -- Make sure we're at least 6 tiles away from the bottom
        -- START OF EVERYTHING
        if y < self.mapHeight - 1 and y > 3 then
            -- FOR THE FIRST QUARTER OF THE MAP
            if y > self.mapHeight * 2/3 then
                
                for counter = 1,self.mapWidth / 2.5 do

                    -- As long as location isn't max,keep incrementing
                    -- NOTICE THE - 7 TO KEEP IT ON ONE SIDE
                    if location < self.mapWidth - 7 then
                        location = location + 1
                    -- If location goes to max,then reset
                    else
                        location = 1
                    end
                 
                    -- Set the tile in the appropriate location
                    self:setTile(location,LID)
                end

            -- FOR THE SECOND QUARTER OF THE MAP,HARDER
            elseif y < self.mapHeight * 2/3 and y > self.mapHeight * 1/3 then
                
                for counter = 1,keep incrementing
                    if location < self.mapWidth then
                        location = location + 1
                    -- If location goes to max,then reset
                    else
                        location = 1
                    end
                 
                    -- Set the tile in the appropriate location
                    -- CHANGING BETWEEN SUSHI COVERS
                    if (counter % 2 == 0) then
                        self:setTile(location,SUSHI1)
                    else
                        self:setTile(location,SUSHI2)
                    end
                
                end
                
            -- FOR THE LAST QUARTER OF THE MAP
            else
                for counter = 1,SUSHI2)
                    end

                end
            end
        end
        -- INCREMENTING SCANLINE
        y = y + 4
    end

end

-- Function to 'Set' what the background tiles should be in the map
function Map:setTileBackground(x,tile)
    self.back[(y - 1) * self.mapWidth + x] = tile
end

-- Function to 'Set' what the tiles should be in the map
function Map:setTile(x,id)
    self.tiles[(y - 1) * self.mapWidth + x] = id
end

-- Function to get the ID of the tile at a certain location
-- This passes the map in as pixel coordinates rather than tile IDs
-- The x and y here are pixel values,getting the tile at that pixel location
-- Note that getTile gets the tile as a TILE,and so needed adjustment
-- The + 1 is because pixel values would make it go back to a pixel based system,and that's
-- 0 indexed. Instead,we want it to be 1 indexed
function Map:tileAt(x,y)
    return {
        x = math.floor(x / self.tileWidth) + 1,y = math.floor(y / self.tileHeight) + 1,id = self:getTile(math.floor(x / self.tileWidth) + 1,math.floor(y / self.tileHeight) + 1)
    }
end

-- Function to figure out what background tile should be in the map
function Map:getTileBackground(x,y)
    return self.back[(y - 1) * self.mapWidth + x]
end

-- Function to figure out what tile should be in the map
function Map:getTile(x,y)
    return self.tiles[(y - 1) * self.mapWidth + x]
end

-- Function to define what the collidables are
function Map:collides(tile)
    -- Define the collidable tiles. It contains the
    -- constants of the tiles that are considered solid
    local collidables = {
        LID,SUSHI1,SUSHI2
    }

    -- This is the function that will be used to check if the tile id that's under us matches 
    --the collidables. It's essentially saying for every key/value pair for ipairs which is 
    -- iterating through all the k/v pairs,and the _ just means index. We aren't using the
    -- key here so it doesn't matter anyway
    for _,v in ipairs(collidables) do
        if tile.id == v then
            return true
        end
    end

    -- Return false if it isn't a collidable
    return false
end

function Map:update(dt)
    -- Updating the player
    self.player:update(dt)

    -- keep camera's coordinate following the player,preventing camera from
    -- scrolling past 0 to the left and the map's width
    self.camX = math.max(0,math.min(self.player.x - VIRTUAL_WIDTH / 2,math.min(self.backgroundWidth - VIRTUAL_WIDTH,self.player.x)))

    self.camY = math.max(0,math.min(self.player.y - VIRTUAL_HEIGHT * 0.815,math.max(self.backgroundHeight - VIRTUAL_HEIGHT,self.player.y)))
end

function Map:render()
    for y = 1,self.mapWidth do
            love.graphics.draw(self.background,self.backgroundSprites[self:getTileBackground(x,y)],(x - 1) * self.backgroundWidth,(y - 1) * self.backgroundHeight)
            love.graphics.draw(self.spritesheet,self.tileSprites[self:getTile(x,(x - 1) * self.tileWidth,(y - 1) * self.tileHeight)
        end
    end

    self.player:render()
end

我的player.lua文件如下:

Player = Class{}

require 'Animation'

-- Know where everything is in the sheet
STEVEN_JUMP = 1
STEVEN_IDLE = 2
STEVEN_WALK1 = 3
STEVEN_WALK2 = 4

-- Setting the movement speed
local MOVE_SPEED = 100

-- Jump velocity,gravity velocity
local JUMP_VELOCITY = 700
local GRAVITY = 40


function Player:init(map)

    -- Initializing the x and y coordinates of the character
    -- NOTE that for the y to be at the bottom,we must subtract the 30 of the platform,and 30
    -- of Steven himself
    self.x = map.tileWidth * 5 -- Essentially 300 pixels to the right
    self.y = map.backgroundHeight - 45

    -- Storing the width and height of the spritesheet
    self.width = 32
    self.height = 30

    -- The dx and dy variables
    self.dx = 0
    self.dy = 0

    -- Easier to type this way
    self.map = map

    -- Storing the spritesheet for Steven
    self.playerSheet = love.graphics.newImage('Graphics/platform/steven/all.png')

    -- Splicing up the spritesheet
    self.frames = generateQuads(self.playerSheet,self.width,self.height)

    -- INITIAL STATE
    self.state = 'idle'

    -- DIRECTION THE CHARACTER IS FACING,DEFAULT
    self.direction = 'right'

    --Animation table
    -- Each takes as an argument the parameters that we used in the Animation
    -- function in the next page,and so it needs textures,frames,etc 
    self.animations = {
        -- IDLE ANIMATION TABLE
        -- Notice that the {} is meant to be an argument into the Animation function,-- or class,but since it's only a table,we don't need to put ({}) but can just
        -- put {}
        ['idle'] = Animation {
            -- The texture that we'll use
            texture = self.texture,-- The frames that we're going to use
            frames = {
                self.frames[2]
            },-- Interval between frames
            interval = 1
        },['walking'] = Animation {
            texture = self.texture,frames = {
                self.frames[3],self.frames[4]
            },interval = 0.15
        },['jumping'] = Animation {
            texture = self.texture,frames = {
                self.frames[1]
            },interval = 1
        }
    }

    -- What the current animation is
    self.animation = self.animations['idle']
    self.currentFrame = self.animation:getCurrentFrame()

    -- Checking the states,returns a function as keys
    self.behaviors = {
        ['idle'] = function(dt)
            -- JUMPING STEVEN
            -- Notice how we need to create a wasPressed function as it's a one-time press
            if love.keyboard.wasPressed('space') then
                --  Set the velocity upwards so negative
                self.dy = -JUMP_VELOCITY
                -- Change the state
                self.state = 'jumping'
                -- Change the animation
                self.animation = self.animations['jumping']
            -- STEVEN MOVES
            elseif love.keyboard.isDown('a') then
                -- Change the direction
                self.direction = 'left'
                -- left movement
                self.dx = -MOVE_SPEED
                -- Change the state
                self.state = 'walking'
                -- Resetting the animation
                self.animations['walking']:restart()
                -- Change the animation
                self.animation = self.animations['walking']
            elseif love.keyboard.isDown('d') then
                -- Change the direction
                self.direction = 'right'
                -- right movement
                self.dx = MOVE_SPEED
                -- Change the state
                self.state = 'walking'
                -- Reset the animation
                self.animations['walking']:restart()
                -- Change the animation
                self.animation = self.animations['walking']
            else
                -- If we aren't pressing a or d,make him idle
                self.dx = 0
            end
        end,['walking'] = function(dt)
            if love.keyboard.wasPressed('space') then
                --  Set the velocity upwards so negative
                self.dy = -JUMP_VELOCITY
                self.state = 'jumping'
                -- Change the animation
                self.animation = self.animations['jumping']
            -- STEVEN MOVES
            elseif love.keyboard.isDown('a') then
                -- Change the direction
                self.direction = 'left'
                -- left movement
                self.dx = -MOVE_SPEED
                -- Change the animation
                self.animation = self.animations['walking']
            elseif love.keyboard.isDown('d') then
                -- Change the direction
                self.direction = 'right'
                -- right movement
                -- Notice we add 80 to account for that weird slow-mo here
                self.dx = MOVE_SPEED
                -- Change the animation
                self.animation = self.animations['walking']
            else
                -- If we aren't pressing a or d,make him idle
                self.dx = 0
                self.state = 'idle'
                self.animation = self.animations['idle']
            end

            -- check if there's a tile directly beneath us
            if not self.map:collides(self.map:tileAt(self.x,self.y + self.height)) and
                not self.map:collides(self.map:tileAt(self.x + self.width - 1,self.y + self.height)) then
                
                -- if so,reset velocity and position and change state
                self.state = 'jumping'
                self.animation = self.animations['jumping']
            end
        end,['jumping'] = function(dt)

            ------------------------------------------- TO DO IF PLAYER GOES UNDER CAMERA BOTTOM ------------------------------------------------------------
            -- break if we go below the surface
            if self.y > self.map.backgroundHeight then

            end

            -- This is to change and manuever in the air
            if love.keyboard.isDown('a') then
                self.direction = 'left'
                -- Change the moving velocity
                self.dx = -MOVE_SPEED
            elseif love.keyboard.isDown('d') then
                self.direction = 'right'
                -- Change the moving velocity
                self.dx = MOVE_SPEED
            end
            -- Setting the y velocity
            self.dy = self.dy + GRAVITY

            -- check if there's a tile directly beneath us
            if self.map:collides(self.map:tileAt(self.x,self.y + self.height)) or
                self.map:collides(self.map:tileAt(self.x + self.width - 1,self.y + self.height)) and self.dy < 0 then

                -- if so,reset velocity and position and change state
                self.dy = 0
                self.state = 'idle'
                self.animation = self.animations['idle']
                self.y = (self.map:tileAt(self.x,self.y + self.height).y - 1) * self.map.tileHeight - self.height
            end
        end
    }

end

function Player:update(dt)
    -- Calling the behaviors as a function
    self.behaviors[self.state](dt)

    --Updating the animation
    self.animation:update(dt)

    -- Get the current frame
    self.currentFrame = self.animation:getCurrentFrame()

    -- Changing the velocities
    self.x = self.x + self.dx * dt
    self.y = self.y + self.dy * dt
end

function Player:render()
    
    -- NOTE the X scaling factor,which is -1 as in to flip if it's right
    local scaleX
    if self.direction == 'right' then
        scaleX = 1
    else
        scaleX = -1
    end

    -- Drawing the character initially
    -- NOTE the extra arguments to change the rotation and OFFSET/FLIP
    -- 0 is the initial rotation,which we don't want
    -- Scaling by -1 changes it to flipping to their right corner,not left,and so
    -- we need to move the origin point (which is initially the top left) to the center
    -- as we want it to change place wrt the origin
    -- The 1 is scaling 1 by Y
    -- The last 2 arguments are adding the offset of whatever its width and height are
    -- ALSO need to account for the origin (since it draws it from the origin) to make
    -- sure Steven isn't floating
    love.graphics.draw(self.playerSheet,self.currentFrame,math.floor(self.x + self.width / 2),math.floor(self.y + self.height / 2),scaleX,1,self.width / 2,self.height / 2)

end

我想做到这一点,例如,如果玩家跳到SUSHI2块上,它将消失。

很抱歉,冗长的帖子。我确实确实想尽我最大的努力,并且尝试添加与普通游戏一样多的内容,但是我是gamelogic的新手,并且不确定如何从屏幕上“删除”图块。我主要是问这个问题,以此作为以后实施时如何消除整个敌人死亡的一种方法,以便它具有某种健康状况条,并且当​​它达到0时,角色将不再出现在屏幕上,因为我我假设这将是相同的逻辑。或者,一旦一些子弹击中了敌人,它们就会从屏幕上消失。无论如何,我们对此表示任何帮助! (我附上了游戏的外观图片以及我的意思是,如果有帮助的话) meow meow

解决方法

似乎您的代码可以处理冲突,并且我假设它可以正常工作,我的猜测是将正在冲突的 SHUSHI2 单元格替换为其中的 EMPTY 单元格值网格,以便销毁。假设您要在跌倒时破坏SUSHI2块,可以采用以下解决方案:

--> Player.behaviors.walking :

    -- check if there's a tile directly beneath us

    -- Let's add a local for the example
    local tile_we_re_falling_on = self.map:tileAt(self.x,self.y + self.height)

    if self.map:collides(tile_we_re_falling_on) or
        self.map:collides(self.map:tileAt(self.x + self.width - 1,self.y + self.height)) and self.dy < 0 then
        if self.dy > 0 and tile_we_re_falling_on.id == SUSHI2 then -- We're falling on a SUSHI2 block/tile
            -- Overwrite the tile to EMPTY
            self.map:setTile(tile_we_re_falling_on.x,tile_we_re_falling_on.y,EMPTY)
            -- Increment some counter,maybe?
        end

        -- if so,reset velocity and position and change state
        self.dy = 0
        self.state = 'idle'
        self.animation = self.animations['idle']
        self.y = (self.map:tileAt(self.x,self.y + self.height).y - 1) * self.map.tileHeight - self.height
    end

希望我能理解您的问题,并且可以有所帮助。您可能需要清理它,感觉有些古怪,但可以说明这个想法。

另一件事是,当您在游戏滴答声中改变世界时,其他一些代码段可能会假设其未更改,这可能会导致某些奇怪的行为。一种常见的做法是,在所有更新逻辑都已运行且不在更新步骤之间的情况下,在帧的开始/结尾推迟改变世界,即可以节省图块ID(x = 2,y = 43)需要更改为EMPTY,并在更新功能结束时应用更改。在这种情况下,我敢肯定会没事的。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


依赖报错 idea导入项目后依赖报错,解决方案:https://blog.csdn.net/weixin_42420249/article/details/81191861 依赖版本报错:更换其他版本 无法下载依赖可参考:https://blog.csdn.net/weixin_42628809/a
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下 2021-12-03 13:33:33.927 ERROR 7228 [ main] o.s.b.d.LoggingFailureAnalysisReporter : *************************** APPL
错误1:gradle项目控制台输出为乱码 # 解决方案:https://blog.csdn.net/weixin_43501566/article/details/112482302 # 在gradle-wrapper.properties 添加以下内容 org.gradle.jvmargs=-Df
错误还原:在查询的过程中,传入的workType为0时,该条件不起作用 &lt;select id=&quot;xxx&quot;&gt; SELECT di.id, di.name, di.work_type, di.updated... &lt;where&gt; &lt;if test=&qu
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct redisServer’没有名为‘server_cpulist’的成员 redisSetCpuAffinity(server.server_cpulist); ^ server.c: 在函数‘hasActiveC
解决方案1 1、改项目中.idea/workspace.xml配置文件,增加dynamic.classpath参数 2、搜索PropertiesComponent,添加如下 &lt;property name=&quot;dynamic.classpath&quot; value=&quot;tru
删除根组件app.vue中的默认代码后报错:Module Error (from ./node_modules/eslint-loader/index.js): 解决方案:关闭ESlint代码检测,在项目根目录创建vue.config.js,在文件中添加 module.exports = { lin
查看spark默认的python版本 [root@master day27]# pyspark /home/software/spark-2.3.4-bin-hadoop2.7/conf/spark-env.sh: line 2: /usr/local/hadoop/bin/hadoop: No s
使用本地python环境可以成功执行 import pandas as pd import matplotlib.pyplot as plt # 设置字体 plt.rcParams[&#39;font.sans-serif&#39;] = [&#39;SimHei&#39;] # 能正确显示负号 p
错误1:Request method ‘DELETE‘ not supported 错误还原:controller层有一个接口,访问该接口时报错:Request method ‘DELETE‘ not supported 错误原因:没有接收到前端传入的参数,修改为如下 参考 错误2:cannot r
错误1:启动docker镜像时报错:Error response from daemon: driver failed programming external connectivity on endpoint quirky_allen 解决方法:重启docker -&gt; systemctl r
错误1:private field ‘xxx‘ is never assigned 按Altʾnter快捷键,选择第2项 参考:https://blog.csdn.net/shi_hong_fei_hei/article/details/88814070 错误2:启动时报错,不能找到主启动类 #
报错如下,通过源不能下载,最后警告pip需升级版本 Requirement already satisfied: pip in c:\users\ychen\appdata\local\programs\python\python310\lib\site-packages (22.0.4) Coll
错误1:maven打包报错 错误还原:使用maven打包项目时报错如下 [ERROR] Failed to execute goal org.apache.maven.plugins:maven-resources-plugin:3.2.0:resources (default-resources)
错误1:服务调用时报错 服务消费者模块assess通过openFeign调用服务提供者模块hires 如下为服务提供者模块hires的控制层接口 @RestController @RequestMapping(&quot;/hires&quot;) public class FeignControl
错误1:运行项目后报如下错误 解决方案 报错2:Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.1:compile (default-compile) on project sb 解决方案:在pom.
参考 错误原因 过滤器或拦截器在生效时,redisTemplate还没有注入 解决方案:在注入容器时就生效 @Component //项目运行时就注入Spring容器 public class RedisBean { @Resource private RedisTemplate&lt;String
使用vite构建项目报错 C:\Users\ychen\work&gt;npm init @vitejs/app @vitejs/create-app is deprecated, use npm init vite instead C:\Users\ychen\AppData\Local\npm-