How to change address in different class?

Right now I am working on a small game for a school project, one of the requirements for such being that it must be object-oriented. Recently I have started splitting up the content of the class that contained the level and such into smaller ones, so that each part of the level would have it’s own subclass within the level class, so basic stuff I assume. The issue I am running into is that I have the handlebuttonevent within the main level class file (the buttons themselves are created using a simple class).

Given that the button changes several addresses specific to the player, I decided to make a simple adress-changing code within the handlebuttoevent like so

 local handleRightButtonEvent = function( event ) if event.phase == "began" and player.buttonLeftHeld == 0 then player.buttonRightHeld = 1 elseif event.phase == "ended" then player.buttonRightHeld = 0 end end

once again, basic stuff.

I then put a runtime event in the player’s class that checks if these are 1 or 0, and applies the appropriate further checks and then makes the changes accordingly. The issue arises in that when I changed player.buttonRightHeld, it does not update within the player class. How would I go about having the address update?

@13068,

  1. Please post a first name in your next post so we don’t have to call you by a number.  I fee like I’m talking to a prisoner or something :slight_smile:

  2. Please be aware the Lua is not really an OOP language, BUT you can still loosely consider some development styles using Lua to be ‘object oriented’ in that you are working with objects and encapsulating data and functionality in them. 

  3. You used the word ‘addresses’ and I’m not sure what you mean.  I hope you don’t mean ‘memory addresses’ because that is not a thing in Lua.  I’ll assume you mean something else and continue on to an answer.

… I’ll give code at the end, but let me continue with the verbiage of the resposne first.

  1. Your touch listener is OK, but it could really do with an upgrade to make it a little more robust.  As it is now, you can have the value set to 1 and never set to 0.  Also, the style of listener isn’t super.  I’ll show an alternative.

  2. Assuming you have a single player that will receive the flag (buttonRightHeld), and assuming you may have more than one button, there is a much nicer way to get this information to your player cleanly and safely.  I’ll show it to you below.

  3. In general, I’d avoid using Runtime events/listeners for touches and collisions.  I know the tutorials here start you off that way, but the do it to get your started with the concepts.  A much better implementation is local listeners (also discussed in the guides).

… OK  enough talking… let me type up some code and I’ll post back in a few minutes.

I forgot to mention…

  1. Your code above has the ‘player’ as a global, which is workable and reasonable if you’re just starting, but I’d learn to avoid that in the future as unnecessary use of globals will get you in trouble.

  2. Your code is probably malfunctioning because of a scope and visibility issue -OR-  because the touch handler is not robust enough.

Now to the code.

A. This code is not meant to simple be dropped into your project.  I mean for you to read it and try to get info from the ideas presented.  I hope it helps and is not too advanced for your current understanding of Corona.

B. This code is fully untested so I may have typoed something.  Please forgive me if I have.  You will need to debug any error message that result on your own and if you get totally stuck, post your code and I or others will try to help

C. You can find references to all the code API calls here: https://docs.coronalabs.com/api/

Player Module

-- ============================================================================ -- Fake player module for the purpose of demonstrating some concepts. -- Probably won't match what you're doing, but I hope it will give you a -- starting point -- ============================================================================ -- Player Module in file: player.lua -- ============================================================================ -- A table to attach fields (if needed) and functions (for sure) to. -- local m = {} -- A simple 'player buider' (won't match yours) function m.new( group, x, y ) -- Supply a default group if group that is passed is 'nil' -- -- Warning: 'display.currentStage' is the top-level group in Corona and -- you do not delete it. -- group = group or display.currentStage -- My dummy player for the example local player = display.newCircle( group, x, y, 100 ) -- Set some playe default fields (OOP-like encapsulation) -- I'm guessing one what you showed in your sample snippet player.buttonUpHeld = false player.buttonDownHeld = false player.buttonLeftHeld = false player.buttonRightHeld = false -- Make a custom event listener using Runtime event -- function player.onButton( self, event ) -- 'self' is player object if( event.type = "right" ) then self.buttonRightHeld = event.held elseif( event.type = "left" ) then self.buttonLeftHeld = event.held elseif( event.type = "up" ) then self.buttonUpHeld = event.held elseif( event.type = "down" ) then self.buttonDownHeld = event.held end end -- 'Listen' for custom event 'onButton' Runtime:addEventListener( "onButton", player ) -- Make an enterFrame listener to do something with current settings.. -- Again, totally fake, but I want to show you some semi-useful code -- for completeness -- function player.enterFrame( self ) -- This statement: ( test ) and A or B -- Means, if the 'test' is true, return A, else return B from the statement. -- self.x = self.x + (( self. buttonRightHeld ) and 1 or 0) self.x = self.x + (( self. buttonLeftHeld ) and -1 or 0) self.y = self.y + (( self. buttonUpHeld ) and -1 or 0) self.y = self.y + (( self. buttonDownHeld ) and 1 or 0) end -- 'Listen' for standard event 'enterFrame' Runtime:addEventListener( "enterFrame", player ) -- Always use a finalize listener to clean up Runtime events attached/ -- listened for, by a object. -- function player.finalize( self ) Runtime:removeEventListener( "onButton", self ) Runtime:removeEventListener( "enterFrame", self ) end -- Start listening for 'finalize' player:addEventListener("finalize") return player end -- Return handle to player module return m

Sample Usage Of Player Module

-- ============================================================================ -- Fake usage of player.lua module for an example only. -- ============================================================================ local playerM = require "player" -- Make player at \<100,100\> and place it in the default group: display.currentStage -- local player = playerM.new( nil, 100, 100 )

Improved Button Touch Listener with Custom Event Usage

-- ============================================================================ -- Fake improved implementation of your touch listener using custom event -- instead of directly manipulating player. -- ============================================================================ -- My dummy 'RIGHT' button: -- local rightButton = display.newRect( 100, 100, 100, 100) -- This listener is compatible with single and multi-touch code -- so it covers all basic usage. -- -- Furthermore, it ensures that the object gets 'began' and 'ended' -- even if you touch the button, slide your finger to the side (off the button) -- and then lift your finger. -- function rightButton.touch( self, event ) local id = event.id local phase = event.phase if( phase == "began" ) then self.isFocus = true display.getCurrentStage():setFocus( self, id ) -- Send out custom event (player will 'hear' this) -- -- The beauty of this is the player object need not be -- in scope or visible for this to work. -- dispatchEvent( { name = "onButton", type = "right", held = true } ) elseif( self.isFocus ) then if( phase == "ended" ) then display.getCurrentStage():setFocus( self, nil ) self.isFocus = false -- Send out custom event (player will 'hear' this) -- dispatchEvent( { name = "onButton", type = "right", held = false } ) end end return true end rightButton:addEventListener( "touch" )

Hello. Okay, so from what I can tell your philosophy is to give general information to allow for learning and such. Normally I would much appreciate and applaud such a manner of doing things. Unfortunately, due to time constraints I cannot really dedicate time to learning the most efficient way of doing things, I was aiming to get only the exact information I required. I understand that I may be doing it horribly inefficiently, but if it works well enough then it is fine, this will never actually be sold or even distributed. :P 

By address I simply mean a variable that is not a table and just has one number - probably not the correct term but I use cheat engine quite a bit so it was the first word that came to mind.

Also, the buttons are meant to be held, so it being possible to constantly be 1 is fine, no?

I do not think the address is a global? Perhaps it would be best if I post both my level class and player class in their entirety, seeing as they are not that long or complex. Please try not to cringe too much at my poor programming :unsure:  :wink:

--======================================================================-- --== Level Factory --======================================================================-- local widget = require( "widget" ) local physics = require( "physics" ) local loadsaveM = require("loadsave") local composer = require( "composer" ) local ButtonClass = require("Classes.Button") local PlayerClass = require("Classes.PlayerClass") local Level = class() -- define level as a class (notice the capitals) Level.\_\_name = "Level" --local LevelBlockClass = require("Classes.LevelBlock") function Level:\_\_init(levelNumber, fullh,centerX,centerY,groupName) self.groupName = groupName self.playState = 0 self.xLocation = xLocation self.yLocation = yLocation self.buttonLeftHeld = 0 self.buttonRightHeld = 0 self.buttonJumpHeld = 0 local playerXSpeed = 90 local playerJumpHeight = 12 self.size = size local tile = {} local tileDimensions = fullh/15 local levelGroup = display.newGroup() local directionBeingHeld = 0 LevelTable = nil print("\nThis is the table after I have nilled it out") --loadsaveM.print\_r(LevelTable) \<-- This prints the table after it has been nilled out and is for testing -- load the tables from files called LevelTable.json and Player Stats.json LevelTable = loadsaveM.loadTable("Level"..levelNumber.."Table.json", system.ResourceDirectory) StatsTable = loadsaveM.loadTable("Player Stats.json", system.ResourceDirectory) if StatsTable[1][isStatChanged] == 1 then playerXSpeed = StatsTable[1][playerXSpeed] playerJumpHeight = StatsTable[1][playerJumpHeight] end --local player = PlayerClass:new(fullh, display.contentCenterX, display.contentCenterY, groupName, levelGroup, self.playState, self.buttonLeftHeld, self.buttonRightHeld, self.buttonJumpHeld, playerXSpeed, playerJumpHeight) --Create the background for the level local function listenerName(event) end Runtime:addEventListener("enterFrame", listenerName) -- local background = display.newImage("images/BackGround"..levelNumber..".png") background.anchorX = 0 background.anchorY = 0 background.height = fullh background.width = fullh\*3 background.x = -45 background.y = 0 background:toBack() local levelEndCarrot = display.newImage("images/BigCarrot.png") levelEndCarrot.anchorX = 0 levelEndCarrot.anchorY = 28 levelEndCarrot.width = pixelScale\*28 levelEndCarrot.height = pixelScale\*35 levelEndCarrot.x = 193\*tileDimensions levelEndCarrot.y = 7\*tileDimensions levelEndCarrot.isFixedRotation=true physics.addBody(levelEndCarrot, "static",{friction=0, bounce=0 }) levelGroup:insert(levelEndCarrot) local levelWidth = #LevelTable --print("■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■ "..levelWidth.." ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■") for i = 1, levelWidth do tile[i]={} for j = 1, 15 do --LevelTable[i][j] --if LevelTable[i][j] == nil then break end local columnName = ("column"..j-1) --print(LevelTable[i][columnName]) \<-- This prints the level table after it has been adapted into a format that can be read by the maker if LevelTable[i][columnName] ~= (-1) then --print(LevelTable[i][j]) \<-- This prints the level table after it has been adapted into a format that can be read by the maker tile[i][j] = display.newImage( "images/overworld"..LevelTable[i][columnName]..".png") tile[i][j].anchorX = 0 tile[i][j].anchorY = 0 tile[i][j].width = tileDimensions tile[i][j].height = tileDimensions tile[i][j].x = (i-3)\*tileDimensions tile[i][j].y = (j-1)\*tileDimensions tile[i][j]:toBack() tile[i][j].isSleepingAllowed = false physics.addBody( tile[i][j], "static",{friction=0.1, bounce=0.01 }) levelGroup:insert(tile[i][j]) end end end -- Function to handle left button events local player = PlayerClass:new(fullh, display.contentCenterX, display.contentCenterY, groupName, levelGroup, self.playState, self.buttonLeftHeld, self.buttonRightHeld, self.buttonJumpHeld, playerXSpeed, playerJumpHeight) local handleLeftButtonEvent = function( event ) if event.phase == "began" and player.buttonRightHeld == 0 then player.buttonLeftHeld = 1 print("moving?") elseif event.phase == "ended" then player.buttonLeftHeld = 0 else print("failed "..player.buttonLeftHeld.." is button state "..event.phase.." is button phase") end print("tried to do stuff") end -- Function to handle right button events local handleRightButtonEvent = function( event ) if event.phase == "began" and player.buttonLeftHeld == 0 then player.buttonRightHeld = 1 elseif event.phase == "ended" then player.buttonRightHeld = 0 end end -- Function to handle jump button events local function handleJumpButtonEvent( event ) if event.phase == "began" and buttonJumpHeld == 0 then player.buttonJumpHeld = 1 elseif event.phase == "ended" and buttonJumpHeld == 1 then player.buttonJumpHeld = 0 end end local buttonLeft = ButtonClass:new(display.contentCenterX\*0.0025, 72\*pixelScale, 12, 12, "LEFT", handleLeftButtonEvent, groupName) local buttonRight = ButtonClass:new(display.contentCenterX\*0.2, 72\*pixelScale, 12, 12, "RIGHT", handleRightButtonEvent, groupName) local buttonJump = ButtonClass:new(display.contentCenterX\*1.9, 72\*pixelScale, 12, 12, "UP", handleJumpButtonEvent, groupName) end return Level

That is the level class, which is called inside a scene. Prior to my recent “cleaning up”, the below player class, as well as the buttons, were also part of the class. I plan to make the tiles their own class as well. A side effect of doing this seems to be that the player suddenly falls extremely slowly, I have no clue if this is due to framerate drops or some sort of glitch, I plan to figure that out once I get the buttons working (assuming that doesn’t fix it).

--======================================================================-- --== PlayerAndControls Class factory --======================================================================-- local widget = require( "widget" ) local PlayerClass = class() -- define Player as a class (notice the capitals) --local LevelClass = require("Classes.Levelmaker") PlayerClass.\_\_name = "PlayerClass" local directionBeingHeld = 0 local buttonJumpHeld = 0 --======================================================================-- --== Require dependant classes --======================================================================-- local physics = require( "physics" ) --======================================================================-- --== Initialization / Constructor --======================================================================-- function PlayerClass:\_\_init(fullh,centerX,centerY, groupName, secondaryGroupName, playState, buttonLeftHeld, buttonRightHeld, buttonJumpHeld, playerXSpeed, playerJumpHeight) self.buttonLeftHeld = 0 self.buttonRightHeld = 0 self.buttonJumpHeld = 0 self.playState = playState self.playerInAir = 0 self.secondaryGroupName = secondaryGroupName self.groupName = groupName self.playerYPos = centerY print(centerY.." is centery "..self.playerYPos.." is playerypos") self.playerXPos = centerX self:drawPlayerClass(fullh,centerX,centerY) local function listenerName(event) --print("here") if player.y \> fullh then playState = 2 print("player fell "..player.y.." "..fullh) Runtime:removeEventListener("enterFrame", listenerName) end if self.buttonLeftHeld == 1 then print("test") ------------------------------------------------------------- -- Timer for increasing horizontal velocity ------------------------------------------------------------- playerTimer = timer.performWithDelay( 10, function() vx, vy = player:getLinearVelocity( ) player:setLinearVelocity( -playerXSpeed, vy) difference = centerX-player.x self.levelGroup.x = difference end, 200) ------------------------------------------------------------- -- Timer for animation sequence changing ------------------------------------------------------------- animationTimer = timer.performWithDelay( 0, function() player:setSequence( "walking" ) player:play() player.xScale = -1\*pixelScale end, 1000) else print(self.buttonLeftHeld) player:setLinearVelocity( 0) directionBeingHeld = 0 player:setSequence( "standing" ) player:play() if playerTimer then timer.cancel(playerTimer) playerTimer = nil end if animationTimer then timer.cancel(animationTimer) animationTimer = nil end end if buttonRightHeld == 1 then ------------------------------------------------------------- -- Timer for increasing horizontal velocity ------------------------------------------------------------- playerTimer = timer.performWithDelay( 10, function() vx, vy = player:getLinearVelocity( ) player:setLinearVelocity( playerXSpeed, vy) difference = centerX-player.x self.levelGroup.x = difference end, 200) ------------------------------------------------------------- -- Timer for animation sequence changing ------------------------------------------------------------- animationTimer = timer.performWithDelay( 0, function() player:setSequence( "walking" ) player:play() player.xScale = 1\*pixelScale end, 1000) else player:setLinearVelocity(0) directionBeingHeld = 0 player:setSequence( "standing" ) player:play() if playerTimer then timer.cancel(playerTimer) playerTimer = nil end if animationTimer then timer.cancel(animationTimer) animationTimer = nil end end if buttonJumpHeld == 1 and playerInAir == 0 then print("jumping") player:applyLinearImpulse( 0, playerJumpHeight) end print(buttonRightHeld) end Runtime:addEventListener("enterFrame", listenerName) end --======================================================================-- --== Code / Methods --======================================================================-- function PlayerClass:drawPlayerClass(fullh,centerX,centerY) --======================================================================-- --== Set up player spritesheet --======================================================================-- -- consecutive frames local sequenceData = { {name="walking", start=1, count=8, time=1000, loopCount = 0, loopDirection = "forward"}, {name="standing", start=1, count=1, time=1000, loopCount = 0, loopDirection = "forward"}, {name="jumping", start=9, count=1, time=1000, loopCount = 0, loopDirection = "forward"} } local playerOptions = { -- Array of tables representing each frame (required) frames = { -- Frame 1 { x = 0, y = 0, width = 9, height = 11 }, -- Frame 2 { x = 9, y = 0, width = 9, height = 11 }, -- Frame 3 { x = 18, y = 0, width = 9, height = 11 }, -- Frame 4 { x = 27, y = 0, width = 9, height = 11 }, -- Frame 5 { x = 36, y = 0, width = 9, height = 11 }, -- Frame 6 { x = 45, y = 0, width = 9, height = 11 }, -- Frame 7 { x = 54, y = 0, width = 9, height = 11 }, -- Frame 8 { x = 63, y = 0, width = 9, height = 11 }, -- Frame 9 { x = 72, y = 0, width = 9, height = 11 }, }, -- Optional parameters; used for scaled content support --sheetContentWidth = 1024, --sheetContentHeight = 1024 } local imageSheet = graphics.newImageSheet( "images/BunnyProtag.png", playerOptions ) --======================================================================-- --== Initializate player --======================================================================-- player = display.newSprite( imageSheet, sequenceData ) player:setSequence( "standing" ) player:play() player:scale( pixelScale, pixelScale ) player.width = pixelScale\*9 player.height = pixelScale\*11 player.x = centerX player.y = centerY physics.addBody(player, "dynamic",{friction=0.1, bounce=0.01 }) player.isFixedRotation=true player.isSleepingAllowed = false --function to handle collision to ground player.myName = "player" local isContact = 0 local function onLocalCollision( self, event ) if ( event.phase == "began" ) --[[and event.y == 0]] then isContact = isContact + 1 playerInAir = 0 elseif ( event.phase == "ended" ) then isContact = isContact - 1 playerInAir = 1 end if isContact \> 0 then playerInAir = 0 elseif isContact \< 0 then playerInAir = 1 end end player.collision = onLocalCollision player:addEventListener( "collision" ) self.groupName:insert( player ) self.secondaryGroupName:insert( player ) return player end function PlayerClass:displayInfo() end --======================================================================-- --== Return factory --======================================================================-- return PlayerClass

This is the player class. All I am trying to do is get it so I can change a variable inside the playerclass and have it actually update. My only solution right now that falls within my knowledge would be to make the button variables globals. Unless I am misunderstanding how complex it would be to implement the things you suggest above, I think I may just ask my teacher or classmates for a more simple solution.

I am sorry if I should not have posted my entire code, but I figured it was small enough to where it was not that much an issue.

If you are still interested in helping and want to call me something just call me Stanley.  :slight_smile:

@13068,

  1. Please post a first name in your next post so we don’t have to call you by a number.  I fee like I’m talking to a prisoner or something :slight_smile:

  2. Please be aware the Lua is not really an OOP language, BUT you can still loosely consider some development styles using Lua to be ‘object oriented’ in that you are working with objects and encapsulating data and functionality in them. 

  3. You used the word ‘addresses’ and I’m not sure what you mean.  I hope you don’t mean ‘memory addresses’ because that is not a thing in Lua.  I’ll assume you mean something else and continue on to an answer.

… I’ll give code at the end, but let me continue with the verbiage of the resposne first.

  1. Your touch listener is OK, but it could really do with an upgrade to make it a little more robust.  As it is now, you can have the value set to 1 and never set to 0.  Also, the style of listener isn’t super.  I’ll show an alternative.

  2. Assuming you have a single player that will receive the flag (buttonRightHeld), and assuming you may have more than one button, there is a much nicer way to get this information to your player cleanly and safely.  I’ll show it to you below.

  3. In general, I’d avoid using Runtime events/listeners for touches and collisions.  I know the tutorials here start you off that way, but the do it to get your started with the concepts.  A much better implementation is local listeners (also discussed in the guides).

… OK  enough talking… let me type up some code and I’ll post back in a few minutes.

I forgot to mention…

  1. Your code above has the ‘player’ as a global, which is workable and reasonable if you’re just starting, but I’d learn to avoid that in the future as unnecessary use of globals will get you in trouble.

  2. Your code is probably malfunctioning because of a scope and visibility issue -OR-  because the touch handler is not robust enough.

Now to the code.

A. This code is not meant to simple be dropped into your project.  I mean for you to read it and try to get info from the ideas presented.  I hope it helps and is not too advanced for your current understanding of Corona.

B. This code is fully untested so I may have typoed something.  Please forgive me if I have.  You will need to debug any error message that result on your own and if you get totally stuck, post your code and I or others will try to help

C. You can find references to all the code API calls here: https://docs.coronalabs.com/api/

Player Module

-- ============================================================================ -- Fake player module for the purpose of demonstrating some concepts. -- Probably won't match what you're doing, but I hope it will give you a -- starting point -- ============================================================================ -- Player Module in file: player.lua -- ============================================================================ -- A table to attach fields (if needed) and functions (for sure) to. -- local m = {} -- A simple 'player buider' (won't match yours) function m.new( group, x, y ) -- Supply a default group if group that is passed is 'nil' -- -- Warning: 'display.currentStage' is the top-level group in Corona and -- you do not delete it. -- group = group or display.currentStage -- My dummy player for the example local player = display.newCircle( group, x, y, 100 ) -- Set some playe default fields (OOP-like encapsulation) -- I'm guessing one what you showed in your sample snippet player.buttonUpHeld = false player.buttonDownHeld = false player.buttonLeftHeld = false player.buttonRightHeld = false -- Make a custom event listener using Runtime event -- function player.onButton( self, event ) -- 'self' is player object if( event.type = "right" ) then self.buttonRightHeld = event.held elseif( event.type = "left" ) then self.buttonLeftHeld = event.held elseif( event.type = "up" ) then self.buttonUpHeld = event.held elseif( event.type = "down" ) then self.buttonDownHeld = event.held end end -- 'Listen' for custom event 'onButton' Runtime:addEventListener( "onButton", player ) -- Make an enterFrame listener to do something with current settings.. -- Again, totally fake, but I want to show you some semi-useful code -- for completeness -- function player.enterFrame( self ) -- This statement: ( test ) and A or B -- Means, if the 'test' is true, return A, else return B from the statement. -- self.x = self.x + (( self. buttonRightHeld ) and 1 or 0) self.x = self.x + (( self. buttonLeftHeld ) and -1 or 0) self.y = self.y + (( self. buttonUpHeld ) and -1 or 0) self.y = self.y + (( self. buttonDownHeld ) and 1 or 0) end -- 'Listen' for standard event 'enterFrame' Runtime:addEventListener( "enterFrame", player ) -- Always use a finalize listener to clean up Runtime events attached/ -- listened for, by a object. -- function player.finalize( self ) Runtime:removeEventListener( "onButton", self ) Runtime:removeEventListener( "enterFrame", self ) end -- Start listening for 'finalize' player:addEventListener("finalize") return player end -- Return handle to player module return m

Sample Usage Of Player Module

-- ============================================================================ -- Fake usage of player.lua module for an example only. -- ============================================================================ local playerM = require "player" -- Make player at \<100,100\> and place it in the default group: display.currentStage -- local player = playerM.new( nil, 100, 100 )

Improved Button Touch Listener with Custom Event Usage

-- ============================================================================ -- Fake improved implementation of your touch listener using custom event -- instead of directly manipulating player. -- ============================================================================ -- My dummy 'RIGHT' button: -- local rightButton = display.newRect( 100, 100, 100, 100) -- This listener is compatible with single and multi-touch code -- so it covers all basic usage. -- -- Furthermore, it ensures that the object gets 'began' and 'ended' -- even if you touch the button, slide your finger to the side (off the button) -- and then lift your finger. -- function rightButton.touch( self, event ) local id = event.id local phase = event.phase if( phase == "began" ) then self.isFocus = true display.getCurrentStage():setFocus( self, id ) -- Send out custom event (player will 'hear' this) -- -- The beauty of this is the player object need not be -- in scope or visible for this to work. -- dispatchEvent( { name = "onButton", type = "right", held = true } ) elseif( self.isFocus ) then if( phase == "ended" ) then display.getCurrentStage():setFocus( self, nil ) self.isFocus = false -- Send out custom event (player will 'hear' this) -- dispatchEvent( { name = "onButton", type = "right", held = false } ) end end return true end rightButton:addEventListener( "touch" )

Hello. Okay, so from what I can tell your philosophy is to give general information to allow for learning and such. Normally I would much appreciate and applaud such a manner of doing things. Unfortunately, due to time constraints I cannot really dedicate time to learning the most efficient way of doing things, I was aiming to get only the exact information I required. I understand that I may be doing it horribly inefficiently, but if it works well enough then it is fine, this will never actually be sold or even distributed. :P 

By address I simply mean a variable that is not a table and just has one number - probably not the correct term but I use cheat engine quite a bit so it was the first word that came to mind.

Also, the buttons are meant to be held, so it being possible to constantly be 1 is fine, no?

I do not think the address is a global? Perhaps it would be best if I post both my level class and player class in their entirety, seeing as they are not that long or complex. Please try not to cringe too much at my poor programming :unsure:  :wink:

--======================================================================-- --== Level Factory --======================================================================-- local widget = require( "widget" ) local physics = require( "physics" ) local loadsaveM = require("loadsave") local composer = require( "composer" ) local ButtonClass = require("Classes.Button") local PlayerClass = require("Classes.PlayerClass") local Level = class() -- define level as a class (notice the capitals) Level.\_\_name = "Level" --local LevelBlockClass = require("Classes.LevelBlock") function Level:\_\_init(levelNumber, fullh,centerX,centerY,groupName) self.groupName = groupName self.playState = 0 self.xLocation = xLocation self.yLocation = yLocation self.buttonLeftHeld = 0 self.buttonRightHeld = 0 self.buttonJumpHeld = 0 local playerXSpeed = 90 local playerJumpHeight = 12 self.size = size local tile = {} local tileDimensions = fullh/15 local levelGroup = display.newGroup() local directionBeingHeld = 0 LevelTable = nil print("\nThis is the table after I have nilled it out") --loadsaveM.print\_r(LevelTable) \<-- This prints the table after it has been nilled out and is for testing -- load the tables from files called LevelTable.json and Player Stats.json LevelTable = loadsaveM.loadTable("Level"..levelNumber.."Table.json", system.ResourceDirectory) StatsTable = loadsaveM.loadTable("Player Stats.json", system.ResourceDirectory) if StatsTable[1][isStatChanged] == 1 then playerXSpeed = StatsTable[1][playerXSpeed] playerJumpHeight = StatsTable[1][playerJumpHeight] end --local player = PlayerClass:new(fullh, display.contentCenterX, display.contentCenterY, groupName, levelGroup, self.playState, self.buttonLeftHeld, self.buttonRightHeld, self.buttonJumpHeld, playerXSpeed, playerJumpHeight) --Create the background for the level local function listenerName(event) end Runtime:addEventListener("enterFrame", listenerName) -- local background = display.newImage("images/BackGround"..levelNumber..".png") background.anchorX = 0 background.anchorY = 0 background.height = fullh background.width = fullh\*3 background.x = -45 background.y = 0 background:toBack() local levelEndCarrot = display.newImage("images/BigCarrot.png") levelEndCarrot.anchorX = 0 levelEndCarrot.anchorY = 28 levelEndCarrot.width = pixelScale\*28 levelEndCarrot.height = pixelScale\*35 levelEndCarrot.x = 193\*tileDimensions levelEndCarrot.y = 7\*tileDimensions levelEndCarrot.isFixedRotation=true physics.addBody(levelEndCarrot, "static",{friction=0, bounce=0 }) levelGroup:insert(levelEndCarrot) local levelWidth = #LevelTable --print("■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■ "..levelWidth.." ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■") for i = 1, levelWidth do tile[i]={} for j = 1, 15 do --LevelTable[i][j] --if LevelTable[i][j] == nil then break end local columnName = ("column"..j-1) --print(LevelTable[i][columnName]) \<-- This prints the level table after it has been adapted into a format that can be read by the maker if LevelTable[i][columnName] ~= (-1) then --print(LevelTable[i][j]) \<-- This prints the level table after it has been adapted into a format that can be read by the maker tile[i][j] = display.newImage( "images/overworld"..LevelTable[i][columnName]..".png") tile[i][j].anchorX = 0 tile[i][j].anchorY = 0 tile[i][j].width = tileDimensions tile[i][j].height = tileDimensions tile[i][j].x = (i-3)\*tileDimensions tile[i][j].y = (j-1)\*tileDimensions tile[i][j]:toBack() tile[i][j].isSleepingAllowed = false physics.addBody( tile[i][j], "static",{friction=0.1, bounce=0.01 }) levelGroup:insert(tile[i][j]) end end end -- Function to handle left button events local player = PlayerClass:new(fullh, display.contentCenterX, display.contentCenterY, groupName, levelGroup, self.playState, self.buttonLeftHeld, self.buttonRightHeld, self.buttonJumpHeld, playerXSpeed, playerJumpHeight) local handleLeftButtonEvent = function( event ) if event.phase == "began" and player.buttonRightHeld == 0 then player.buttonLeftHeld = 1 print("moving?") elseif event.phase == "ended" then player.buttonLeftHeld = 0 else print("failed "..player.buttonLeftHeld.." is button state "..event.phase.." is button phase") end print("tried to do stuff") end -- Function to handle right button events local handleRightButtonEvent = function( event ) if event.phase == "began" and player.buttonLeftHeld == 0 then player.buttonRightHeld = 1 elseif event.phase == "ended" then player.buttonRightHeld = 0 end end -- Function to handle jump button events local function handleJumpButtonEvent( event ) if event.phase == "began" and buttonJumpHeld == 0 then player.buttonJumpHeld = 1 elseif event.phase == "ended" and buttonJumpHeld == 1 then player.buttonJumpHeld = 0 end end local buttonLeft = ButtonClass:new(display.contentCenterX\*0.0025, 72\*pixelScale, 12, 12, "LEFT", handleLeftButtonEvent, groupName) local buttonRight = ButtonClass:new(display.contentCenterX\*0.2, 72\*pixelScale, 12, 12, "RIGHT", handleRightButtonEvent, groupName) local buttonJump = ButtonClass:new(display.contentCenterX\*1.9, 72\*pixelScale, 12, 12, "UP", handleJumpButtonEvent, groupName) end return Level

That is the level class, which is called inside a scene. Prior to my recent “cleaning up”, the below player class, as well as the buttons, were also part of the class. I plan to make the tiles their own class as well. A side effect of doing this seems to be that the player suddenly falls extremely slowly, I have no clue if this is due to framerate drops or some sort of glitch, I plan to figure that out once I get the buttons working (assuming that doesn’t fix it).

--======================================================================-- --== PlayerAndControls Class factory --======================================================================-- local widget = require( "widget" ) local PlayerClass = class() -- define Player as a class (notice the capitals) --local LevelClass = require("Classes.Levelmaker") PlayerClass.\_\_name = "PlayerClass" local directionBeingHeld = 0 local buttonJumpHeld = 0 --======================================================================-- --== Require dependant classes --======================================================================-- local physics = require( "physics" ) --======================================================================-- --== Initialization / Constructor --======================================================================-- function PlayerClass:\_\_init(fullh,centerX,centerY, groupName, secondaryGroupName, playState, buttonLeftHeld, buttonRightHeld, buttonJumpHeld, playerXSpeed, playerJumpHeight) self.buttonLeftHeld = 0 self.buttonRightHeld = 0 self.buttonJumpHeld = 0 self.playState = playState self.playerInAir = 0 self.secondaryGroupName = secondaryGroupName self.groupName = groupName self.playerYPos = centerY print(centerY.." is centery "..self.playerYPos.." is playerypos") self.playerXPos = centerX self:drawPlayerClass(fullh,centerX,centerY) local function listenerName(event) --print("here") if player.y \> fullh then playState = 2 print("player fell "..player.y.." "..fullh) Runtime:removeEventListener("enterFrame", listenerName) end if self.buttonLeftHeld == 1 then print("test") ------------------------------------------------------------- -- Timer for increasing horizontal velocity ------------------------------------------------------------- playerTimer = timer.performWithDelay( 10, function() vx, vy = player:getLinearVelocity( ) player:setLinearVelocity( -playerXSpeed, vy) difference = centerX-player.x self.levelGroup.x = difference end, 200) ------------------------------------------------------------- -- Timer for animation sequence changing ------------------------------------------------------------- animationTimer = timer.performWithDelay( 0, function() player:setSequence( "walking" ) player:play() player.xScale = -1\*pixelScale end, 1000) else print(self.buttonLeftHeld) player:setLinearVelocity( 0) directionBeingHeld = 0 player:setSequence( "standing" ) player:play() if playerTimer then timer.cancel(playerTimer) playerTimer = nil end if animationTimer then timer.cancel(animationTimer) animationTimer = nil end end if buttonRightHeld == 1 then ------------------------------------------------------------- -- Timer for increasing horizontal velocity ------------------------------------------------------------- playerTimer = timer.performWithDelay( 10, function() vx, vy = player:getLinearVelocity( ) player:setLinearVelocity( playerXSpeed, vy) difference = centerX-player.x self.levelGroup.x = difference end, 200) ------------------------------------------------------------- -- Timer for animation sequence changing ------------------------------------------------------------- animationTimer = timer.performWithDelay( 0, function() player:setSequence( "walking" ) player:play() player.xScale = 1\*pixelScale end, 1000) else player:setLinearVelocity(0) directionBeingHeld = 0 player:setSequence( "standing" ) player:play() if playerTimer then timer.cancel(playerTimer) playerTimer = nil end if animationTimer then timer.cancel(animationTimer) animationTimer = nil end end if buttonJumpHeld == 1 and playerInAir == 0 then print("jumping") player:applyLinearImpulse( 0, playerJumpHeight) end print(buttonRightHeld) end Runtime:addEventListener("enterFrame", listenerName) end --======================================================================-- --== Code / Methods --======================================================================-- function PlayerClass:drawPlayerClass(fullh,centerX,centerY) --======================================================================-- --== Set up player spritesheet --======================================================================-- -- consecutive frames local sequenceData = { {name="walking", start=1, count=8, time=1000, loopCount = 0, loopDirection = "forward"}, {name="standing", start=1, count=1, time=1000, loopCount = 0, loopDirection = "forward"}, {name="jumping", start=9, count=1, time=1000, loopCount = 0, loopDirection = "forward"} } local playerOptions = { -- Array of tables representing each frame (required) frames = { -- Frame 1 { x = 0, y = 0, width = 9, height = 11 }, -- Frame 2 { x = 9, y = 0, width = 9, height = 11 }, -- Frame 3 { x = 18, y = 0, width = 9, height = 11 }, -- Frame 4 { x = 27, y = 0, width = 9, height = 11 }, -- Frame 5 { x = 36, y = 0, width = 9, height = 11 }, -- Frame 6 { x = 45, y = 0, width = 9, height = 11 }, -- Frame 7 { x = 54, y = 0, width = 9, height = 11 }, -- Frame 8 { x = 63, y = 0, width = 9, height = 11 }, -- Frame 9 { x = 72, y = 0, width = 9, height = 11 }, }, -- Optional parameters; used for scaled content support --sheetContentWidth = 1024, --sheetContentHeight = 1024 } local imageSheet = graphics.newImageSheet( "images/BunnyProtag.png", playerOptions ) --======================================================================-- --== Initializate player --======================================================================-- player = display.newSprite( imageSheet, sequenceData ) player:setSequence( "standing" ) player:play() player:scale( pixelScale, pixelScale ) player.width = pixelScale\*9 player.height = pixelScale\*11 player.x = centerX player.y = centerY physics.addBody(player, "dynamic",{friction=0.1, bounce=0.01 }) player.isFixedRotation=true player.isSleepingAllowed = false --function to handle collision to ground player.myName = "player" local isContact = 0 local function onLocalCollision( self, event ) if ( event.phase == "began" ) --[[and event.y == 0]] then isContact = isContact + 1 playerInAir = 0 elseif ( event.phase == "ended" ) then isContact = isContact - 1 playerInAir = 1 end if isContact \> 0 then playerInAir = 0 elseif isContact \< 0 then playerInAir = 1 end end player.collision = onLocalCollision player:addEventListener( "collision" ) self.groupName:insert( player ) self.secondaryGroupName:insert( player ) return player end function PlayerClass:displayInfo() end --======================================================================-- --== Return factory --======================================================================-- return PlayerClass

This is the player class. All I am trying to do is get it so I can change a variable inside the playerclass and have it actually update. My only solution right now that falls within my knowledge would be to make the button variables globals. Unless I am misunderstanding how complex it would be to implement the things you suggest above, I think I may just ask my teacher or classmates for a more simple solution.

I am sorry if I should not have posted my entire code, but I figured it was small enough to where it was not that much an issue.

If you are still interested in helping and want to call me something just call me Stanley.  :slight_smile: