Dynamically created GUI in Roblox - user-interface

I am coding my first game using lua and roblox studio. I have a couple of questions regarding GUI. I have coded a very rudimentary gui that displays the code of the four teams that can join the game. Here is the code for the GUI. It lives in a local script inside StarterGUI:
local UpdateGUI = game.ReplicatedStorage:WaitForChild("UpdateGUI")
local StartGui = game.ReplicatedStorage:WaitForChild("StartGui")
local UpdateAllScoresLateArrival = game.ReplicatedStorage:WaitForChild("UpdateAllScoresLateArrival")
local function updateAllLabelsLateArrival(redPoints, bluePoints, yellowPoints, greenPoints)
game.Players.LocalPlayer.PlayerGui.ScreenGui.RedTeam.Text = redPoints
game.Players.LocalPlayer.PlayerGui.ScreenGui.BlueTeam.Text = bluePoints
game.Players.LocalPlayer.PlayerGui.ScreenGui.YellowTeam.Text = yellowPoints
game.Players.LocalPlayer.PlayerGui.ScreenGui.GreenTeam.Text = greenPoints
end
local function UpdateLabel(plr, points)
if plr.team.Name == "Really red Team" then
game.Players.LocalPlayer.PlayerGui.ScreenGui.RedTeam.Text = points
elseif plr.team.Name == "Really blue Team" then
game.Players.LocalPlayer.PlayerGui.ScreenGui.BlueTeam.Text = points
elseif plr.team.Name == "New Yeller Team" then
game.Players.LocalPlayer.PlayerGui.ScreenGui.YellowTeam.Text = points
elseif plr.team.Name == "Lime green Team" then
game.Players.LocalPlayer.PlayerGui.ScreenGui.GreenTeam.Text = points
end
end
local localPlayer = game.Players.LocalPlayer
local function StartLabel(player)
if player.Team.Name == "Really red Team" then
game.Players.LocalPlayer.PlayerGui.ScreenGui.RedTeam.TextTransparency = 0
game.Players.LocalPlayer.PlayerGui.ScreenGui.RedTeamTag.TextTransparency = 0
game.Players.LocalPlayer.PlayerGui.ScreenGui.RedTeam.TextStrokeTransparency = 0
game.Players.LocalPlayer.PlayerGui.ScreenGui.RedTeamTag.TextStrokeTransparency = 0
game.Players.LocalPlayer.PlayerGui.ScreenGui.RedTeamTag.BackgroundTransparency = 0.5
elseif player.Team.Name == "Really blue Team" then
game.Players.LocalPlayer.PlayerGui.ScreenGui.BlueTeam.TextTransparency = 0
game.Players.LocalPlayer.PlayerGui.ScreenGui.BlueTeamTag.TextTransparency = 0
game.Players.LocalPlayer.PlayerGui.ScreenGui.BlueTeam.TextStrokeTransparency = 0
game.Players.LocalPlayer.PlayerGui.ScreenGui.BlueTeamTag.TextStrokeTransparency = 0
game.Players.LocalPlayer.PlayerGui.ScreenGui.BlueTeamTag.BackgroundTransparency = 0.5
elseif player.Team.Name == "New Yeller Team" then
game.Players.LocalPlayer.PlayerGui.ScreenGui.YellowTeam.TextTransparency = 0
game.Players.LocalPlayer.PlayerGui.ScreenGui.YellowTeamTag.TextTransparency = 0
game.Players.LocalPlayer.PlayerGui.ScreenGui.YellowTeam.TextStrokeTransparency = 0
game.Players.LocalPlayer.PlayerGui.ScreenGui.YellowTeamTag.TextStrokeTransparency = 0
game.Players.LocalPlayer.PlayerGui.ScreenGui.YellowTeamTag.BackgroundTransparency = 0.5
elseif player.Team.Name == "Lime green Team" then
game.Players.LocalPlayer.PlayerGui.ScreenGui.GreenTeam.TextTransparency = 0
game.Players.LocalPlayer.PlayerGui.ScreenGui.GreenTeamTag.TextTransparency = 0
game.Players.LocalPlayer.PlayerGui.ScreenGui.GreenTeam.TextStrokeTransparency = 0
game.Players.LocalPlayer.PlayerGui.ScreenGui.GreenTeamTag.TextStrokeTransparency = 0
game.Players.LocalPlayer.PlayerGui.ScreenGui.GreenTeamTag.BackgroundTransparency = 0.5
end
end
UpdateGUI.OnClientEvent:Connect(UpdateLabel)
StartGui.OnClientEvent:Connect(StartLabel)
UpdateAllScoresLateArrival.OnClientEvent:Connect(updateAllLabelsLateArrival)
There is a function that starts the label that is triggered in a server side script when a player joins the game. By ''start the label'' I mean that the labels are there with a transparency of 1 and the function makes them visible when a player joins. There is a function that updates the label everytime any player scores, and a function that is triggered also when a player joins the game late to make sure it has the scores of the players already in the game. Like I said this is my first game and I was focusing on things working. Now I would like to code it properly. My goal is that the labels are allocated dynamically. That is, when a player joins the game, the label is created in code. Particularly I would want the space between the labels to be set dynamically so that the labels are centred regardless of how many players. I tried making the labels a child of a ''frame'' but the labels changed place and were difficult to manipulate. So I would like some advice as to how to set this up in code.

My goal is that the labels are allocated dynamically. That is, when a player joins the game, the label is created in code
You can create UI elements the same way you create Instances in the Workspace.
local lblTeam = Instance.new("TextLabel")
lblTeam.TextTransparency = 0
lblTeam.TextStrokeTransparency = 0
lblTeam.Name = teamName
lblTeam.Parent = game.Players.LocalPlayer.PlayerGui.ScreenGui
I would want the space between the labels to be set dynamically so that the labels are centered regardless of how many players there are.
The way UI elements are laid out in Roblox are with UDim2 values for Size and Position.
A UDim2's constructor looks like this : UDim2.new(xScale, xOffset, yScale, yOffset). Scale refers to with percentage of the parent container should this dimension span, and Offset are the number of pixels extra to add. So some examples :
local lbl = Instance.new("TextLabel")
lbl.Size = UDim2.new(0, 50, 0, 10) -- 50 pixel wide and 10 pixel tall
lbl.Size = UDim2.new(1, 0, 1, 0) -- 100% wide by 100% tall
lbl.Size = UDim2.new(1, -10, 1, -10) -- 100% wide and tall, minus 10 pixels on both bottom and right
-- assuming no changes to AnchorPoint...
lbl.Position = UDim2.new(0, 0, 0, 0) -- upper left corner is upper left corner of parent
lbl.Position = UDim2.new(0.5, 0, 0.5, 0) -- upper left corner is dead center
lbl.Position = UDim2.new(1, 0, 0, 0) -- upper left corner is offscreen on the right
Now, if you want your stuff to be dynamically placed, you could manually place these objects using Positions, but I would recommend using a UIListLayout object and using the LayoutIndex property to automatically place objects for you. It will automatically handle the Position property for you.
local function createTeamUI(name, parent, teamName, index)
-- make a small frame to hold each team UI
-- looks like : [[ Team Tag Label ][ Team Points Label ]]
local teamFrm = Instance.new("Frame")
teamFrm.BackgroundTransparency = 1
teamFrm.Size = UDim2.new(1, 0, 0, 30) -- relative to parent : 100% wide, 30px tall
teamFrm.Name = name
teamFrm.LayoutIndex = index
local lblTeamTag = Instance.new("TextLabel", teamFrm)
lblTeamTag.TextTransparency = 0
lblTeamTag.TextStrokeTransparency = 0
lblTeamTag.Name = "TeamTag"
lblTeamTag.Text = teamName
lblTeamTag.Size = UDim2.new(0.5, 0, 1, 0) -- relative to teamFrm : 50% wide, 100% tall
lblTeam.Position = UDim2.new(0, 0, 0, 0)
local lblPoints = Instance.new("TextLabel", teamFrm)
lblPoints.TextStrokeTransparency = 0
lblPoints.BackgroundTransparency = 0.5
lblPoints.Name = "Points"
lblPoints.Text = "0"
lblPoints.Size = UDim2.new(0.5, 0, 1, 0) -- relative to teamFrm
lblPoints.Position = UDim2.new(0.5, 0, 0, 0)
-- optimization : set the parent last
teamFrm.Parent = parent
return teamFrm
end
local function createAllTeamLabels()
-- creates a list of UI
local frm = Instance.new("Frame")
frm.Name = "Teams"
frm.Size = UDim2.new(0.3, 0, 1, 0)
frm.BackgroundTransparency = 1.0
local layout = Instance.new("UIListLayout")
layout.LayoutOrder = Enum.SortOrder.LayoutIndex
layout.FillDirection = Enum.FillDirection.Vertical
layout.Padding = UDim.new(0, 10) -- 10 pixels between each element in the list
local frmTeamA = createTeamLabel("RedTeam", frm, "Really Red Team", 0)
local frmTeamB = createTeamLabel("BlueTeam", frm, "Blue Team", 1)
local frmTeamC = createTeamLabel("GreenTeam", frm, "Green Team", 2)
frm.Parent = game.Players.LocalPlayer.PlayerGui.ScreenGui
end
local function updatePoints(teamName, points)
game.Players.LocalPlayer.PlayerGui.ScreenGui.Teams[teamName].Points.Text = tostring(points)
end
I have noticed that when a player dies, the GUI disappears on respawn
There is a property on ScreenGuis called ResetOnSpawn that you can change to false. That will keep the UI around even after a player resets.
Since you are making your UI dynamically in code, you should be careful that you aren't accidentally creating the UI multiple times. Here's where the differences between StarterPlayer > StarterPlayerScripts and StarterPlayer > StarterCharacterScripts become important. A LocalScript inside StarterPlayerScripts will run when the player first joins, and a LocalScript inside StarterCharacterScripts will run every time the player's character reloads. So be careful where you fire the code to create the UI.
Hope this helps!

Related

love2d connecting line segment objects to make a pencil tool that draws lines

I'm trying to create a game that is similar to line rider. I've kind of programmed a pencil right now except that the lines are scattered objects.
I want to be able to connect those red dots to make a smooth line so that the ball can roll across it.
It should more look like this
This is my code
function love.load()
printx = 0 --position to be drawn on when the mouse is pressed
printy = 0 --position to be drawn on when the mouse is pressed
love.physics.setMeter(64) --the height of a meter our worlds will be 64px
world = love.physics.newWorld(0, 9.81*64, true) --The world the everything exists in. Horizontal gravity=0. Bertical gravity=9.81. True says that the world is allowed to sleep.
objects = {} -- table to hold all our physical objects
--let's create the ground
objects.lines = {}
objects.ground = {}
objects.ground.body = love.physics.newBody(world, 650/2, 650-50/2)
objects.ground.shape = love.physics.newRectangleShape(650, 50) --make a rectangle with a width of 650 and a height of 50
objects.ground.fixture = love.physics.newFixture(objects.ground.body, objects.ground.shape); --attach shape to body
--let's create a ball
objects.ball = {}
objects.ball.body = love.physics.newBody(world, 650/2, 600, "dynamic") --Determines where the object will start. In the center of the world and dynamic(moves around)
objects.ball.shape = love.physics.newCircleShape(20) --the ball's shape has a radius of 20
objects.ball.fixture = love.physics.newFixture(objects.ball.body, objects.ball.shape, 1) -- Attach fixture to body and give it a density of 1.
--initial graphics setup
love.graphics.setBackgroundColor(0.41, 0.53, 0.97) --set the background color to a nice blue
love.window.setMode(650, 650) --set the window dimensions to 650 by 650
end
function love.update(dt)
world:update(dt) --this puts the world into motion
if love.mouse.isDown(1) then
local printx = love.mouse.getX()
local printy = love.mouse.getY()
line = {}
line.body = love.physics.newBody(world, printx, printy, "static")
line.shape = love.physics.newRectangleShape(0, 0, 5, 5)
line.fixture = love.physics.newFixture(line.body, line.shape, 5) -- A higher density gives it more mass.
table.insert(objects.lines, line)
love.graphics.setColor(50,50,50)
love.graphics.polygon("fill", line.body:getWorldPoints(line.shape:getPoints()))
end
end
function love.draw()
love.graphics.setColor(0.28, 0.63, 0.05) -- set the drawing color to green for the ground
love.graphics.polygon("fill", objects.ground.body:getWorldPoints(objects.ground.shape:getPoints())) -- draw a "filled in" polygon using the ground's coordinates
love.graphics.setColor(0.76, 0.18, 0.05) --set the drawing color to red for the ball
love.graphics.circle("fill", objects.ball.body:getX(), objects.ball.body:getY(), objects.ball.shape:getRadius())
for _, block in pairs(objects.lines) do
love.graphics.polygon("fill", block.body:getWorldPoints(block.shape:getPoints()))
end
end
Within love.update
if not love.mouse.isDown(1) then
oldx = nil
oldy = nil
end
--draw lines when the mouse is down
if love.mouse.isDown(1) then
local printx = love.mouse.getX() + Camera.x --x coordinate of the mouse
local printy = love.mouse.getY() + Camera.y --y coordinate of the mouse
if oldx ~= nil then
line = {}
line.x1 = oldx
line.x2 = printx
line.y1 = oldy
line.y2 = printy
line.body = love.physics.newBody(world, 0, 0, "static")
line.shape = love.physics.newEdgeShape(printx, printy, oldx, oldy)
line.fixture = love.physics.newFixture(line.body, line.shape, 5)
table.insert(objects.lines, line)
end
oldx = printx
oldy = printy
end
Within love.draw()
for _, line in pairs(objects.lines) do
love.graphics.line( line.x1 - Camera.x, line.y1 - Camera.y, line.x2 - Camera.x, line.y2 - Camera.y) --:getWorldPoints(block.shape:getPoints()))
end

Create a random background image for gui

I am trying to create a function that will choose a picture for the background image for my gui at random. I tried doing this by creating random integers from 1 to 6 (i have 6 different background images to choose from) and then writing if statements where if the integer is equal to a certain value, then a certain image will be called. it works the first time I run the gui, and then every time after that I just get a grey background and no image.
% creates the 'background' axes
ha = axes('units','normalized','position',[0 0 1 1]);
% Move the background axes to the bottom
uistack(ha,'bottom');
% Load in a random background image and display it using the correct colors
bg = randi(6); % random integer
handles.p = 0; % background image variable
% pick a background based on random integer
if bg == 1
handles.p = imread('dark.jpg');
elseif bg == 2
handles.p = imread('powerup.PNG');
elseif bg == 2
handles.p = imread('what.jpg');
elseif bg == 2
handles.p = imread('earth.PNG');
elseif bg == 2
handles.p = imread('namek.PNG');
elseif bg == 2
handles.p = imread('namekexplode.PNG');
end
hi = imagesc(handles.p);
colormap gray;
% Turn the handlevisibility off and make the axes invisible
set(ha,'handlevisibility','off', 'visible','off');
clearvars handles.p
This is my attempt. Please help
You've written bg == 2 repeatedly instead of 3, 4, 5 ...

Move an image using a spritesheet in an if statement

I have a beaver that is meant to follow the user frog. It moves in the direction of the frog at a slower pace. However I want the beaver to have a left and right animation. So I have the movement working, just not the animation.
local BidoofSheetData =
{
width = 32,
height = 48,
numFrames = 8,
sheetContentWidth = 128,
sheetcontentheight = 96
}
--Set File Actual size
bidoofSheet = graphics.newImageSheet ("BidoofSpriteSheet.png", BidoofSheetData)
--Set the sequences
local bidoofsequenceData = {
{name = "bstop", start = 1, count = 1, time = 300},
{name = "bleft", start = 2, count = 3, time = 300},
{name = "bright", start = 5, count = 3, time = 300}
}
--frog mask
local physicsData = (require "bidoofdefs").physicsData(1.0)
--Link sheet data to previous settings
beaver = display.newSprite(bidoofSheet, bidoofsequenceData)
beaver.x = display.contentWidth/2
beaver.y = 284
physics.addBody( beaver, "static")
beaver.isFixedRotation = true
--
function moveBeaver ()
if frog.x > beaver.x then
beaver.x = beaver.x + 0.5
elseif frog.x < beaver.x then
beaver.x = beaver.x - 0.5
elseif frog.x == beaver.x then
beaver.x = beaver.x
end
end
Runtime:addEventListener("enterFrame", moveBeaver)
I've tried to add it in the moveBeaver function, but it doesn't work.
EDIT:
i tried adding beaver:setSequence("bleft");beaver:play() into the different areas. it played one frame for left and one for right if you move in the respective directions. if you move to far left or right and stopped, it would play both left and right frames constantly.
but it didn't play the 3 frame animation i want it to.
First off, I noticed an inconsistency in your sheet data.
local BidoofSheetData =
{
width = 32,
height = 48,
numFrames = 8,
sheetContentWidth = 128,
sheetcontentheight = 96 -- Shouldn't this be sheetContentHeight ?
}
I'm not sure if having the proper capitalization of sheetContentHeight matters, but I thought I'd bring it up. I think I know what the issue is with your animation now. You were setting it to play any time the beaver needed to move, which would reset it to the first frame of the animation.
Try this instead:
function updateAnim(who, seq)
if who.sequence == seq then
-- We're already animating the way we need to be.
return
end
who:setSequence(seq)
who:play()
end
function moveBeaver()
-- Get the distance from beaver to frog's position.
local d = frog.x - beaver.x
-- This will allow the beaver to stop precisely on the frog's position,
-- without exceeding a distance of +/- 0.5 per move.
if d == 0 then
updateAnim(beaver, "bstop")
elseif d > 0 then
beaver.x = beaver.x + math.min(d, 0.5)
updateAnim(beaver, "bright")
else
beaver.x = beaver.x + math.max(d, -0.5)
updateAnim(beaver, "bleft")
end
end

Two seperate listeners for same object Corona

I created a display group and put some items in it and added a listener for slide function that slides the display group to reach the items outside of the screen and come back. I also want to add a touch listener for those items which calls the function which drags items. So how can I achieve that without interfering those listeners with each other?
Here is the pic:
I put all those circles and numbers on blue rectangle to a display group and I added a touch event listener for that group:
ballGroup.touch=slide
ballGroup:addEventListener("touch", ballGroup)
I also want to be able to add another touch event listener for balls:
function createBall()
local ball = display.newCircle(x, H/2-25, 50)
local label = display.newText(""..count, ball.x, ball.y, nil , 35)
label:setTextColor ( 255, 0, 0 )
ball.no = count
ball.touch=chooseBall
ball:addEventListener("touch", ball)
ballGroup:insert(ball)
ballGroup:insert(label)
count=count+1
x=x+120
end
However, it's just listening the event of the function that I write first. What do you suggest me to achieve what I want? When I try to slide the balls, I just want it to listen slide event and when I try to drag the balls, I want it to listen drag event. How can I do that?
Okey, I am sharing the whole code that I came up with after Rob's suggestion but it is still not working and the Outlaw IDE gives that error:
attempt to perform arithmetic on x0(nil value) and the line is where the moved phase is in the slide function.
Here is the whole code:
W=display.contentWidth
H=display.contentHeight
local ballGroup = display.newGroup()--balls and numbers will be added
local x=50 --for ball's locating
local count=1 -- little ball's number starting from 1
local rect --background rect for balls
--big circle at the bottom
local circle = display.newCircle(W/2, H-90, 70)
local circleTxt = display.newText("", 0, 0, nil, 50 )
circleTxt:setTextColor ( 255, 0, 0 )
circleTxt.x=circle.x; circleTxt.y = circle.y
--Dragging ball and checking if it is inside big circle if it is so, remove ball and show the number of ball on big circle
function dragBall(self, event)
if event.phase=="began" then
display.getCurrentStage ( ):setFocus(self, event.id)
self.isFocus=true
self.x0= self.x; self.y0=self.y
elseif event.phase=="moved" then
local dx = math.abs( event.x - event.xStart ) -- Get the x- transition of the touch-input
local dy = math.abs( event.y - event.yStart ) -- Get the y-transition of the touch-input
if dy < 5 then --I changed it to less than, because if y is bigger,then focus should stay on the ball which will be dragged
display.getCurrentStage():setFocus( nil )
event.target.isFocus = false
return false
end
self.x = self.x0+(event.x-event.xStart); self.y = self.y0+(event.y-event.yStart) --drag ball
elseif event.phase=="cancelled" or event.phase=="ended" then
checkArea(self)
display.getCurrentStage():setFocus(self,nil)
end
return true
end
function createBall()
local ball = display.newCircle(x, H/2-25, 50)
local label = display.newText(""..count, ball.x, ball.y, nil , 35)
label:setTextColor ( 255, 0, 0 )
ball.no = count
ball.touch=dragBall
ball:addEventListener("touch", ball)
ballGroup:insert(ball)
ballGroup:insert(label)
count=count+1
x=x+120
end
for i=1,8 do
createBall()
end
rect = display.newRect(0,0, ballGroup.width, ballGroup.height); rect.y=H/2-25
rect:setFillColor(0,0,255)
rect:toBack()
function slide(self, event)
if event.phase=="began" then
self.x0=self.x
self.y0=self.y
display.getCurrentStage():setFocus(self, event.id)
self.isFocus=true
elseif event.phase=="moved" then
local dif = event.x-event.xStart
self.x = self.x0+dif
if ballGroup.contentBounds.xMax < W then
ballGroup.x = ballGroup.x+(W-ballGroup.contentBounds.xMax)
elseif ballGroup.contentBounds.xMin > 0 then
ballGroup.x = 0
end
elseif event.phase=="cancelled" or event.phase=="ended" then
display.getCurrentStage():setFocus(nil)
self.isFocus=false
end
return true
end
ballGroup.touch=slide
ballGroup:addEventListener("touch", ballGroup)
local bounds = circle.contentBounds
local xMax = bounds.xMax
local xMin = bounds.xMin
local yMax = bounds.yMax
local yMin = bounds.yMin
function checkArea(self)
if self.x>xMin and self.x<xMax and self.y>yMin and self.y<yMax then
circleTxt.text=""..self.no
self:removeSelf()
self=nil
end
end
My Solution is put Runtime Touch Lister:
if event.phase == "began" then
startx = event.x
elseif event.phase == "ended" then
local endx = event.x
result_postion = endx-startx
if result_postion >50 then
print("right swipe")
elseif result_postion <50 then
print("left swipe")
end
end
After Object(ball) touch Function
local function ball(event)
if event.phase == "began" then
startpos = event.x
display.getCurrentStage():setFocus(event.target)
elseif event.phase == "moved" then
endpos = event.x
result = endpos-startpos
if result<30 and result>=-30 then
print("correct")
end
end
end
You can have a listener on the scroll area and a listener on the circles. The handler for the circles need to test to see if the event.phase is "moved" and if you've moved say more than 5px, then you want to release the focus on the circle and return false, letting the event propogate to the underlying object.
elseif event.phase == "moved" then -- Check if you moved your finger while touching
local dx = math.abs( event.x - event.xStart ) -- Get the x-transition of the touch-input
local dy = math.abs( event.y - event.yStart ) -- Get the y-transition of the touch-input
if dx > 5 or dy > 5 then
display.getCurrentStage():setFocus( nil )
event.target.isFocus = false
return false
end
end
or something like that.

Bouncing text animation issue in Pygame

I'm trying to code a program that can take text and animate it to bounce on a loop, like a ball bouncing to the floor. I used a similar piece of code I found a starting point as I'm still fairly new to Pygame (thank you Pete Shinners, whoever you are), but after updating the code and playing with it for a long time I still can't get it to blit to the screen correctly. The text starts above the rendered area and then gradually falls into view, but the top part of the text is cut off.
I've tried moving the blitted region around the window and resizing the rectangles and surface the program is using, but nothing seems to fix it.
import os, sys, math, pygame, pygame.font, pygame.image
from pygame.locals import *
def bounce():
# define constants
G = 0.98
FLOOR = 0
COEFFICIENT = 0.8
#define variables
ball = 500
direction = 'DOWN'
v = 0
count = 0
#create array to store data
array = [ball]
while True:
if count == 4:
return array
elif ball > FLOOR and direction == 'DOWN':
v += G
if (ball - v) >= FLOOR:
ball = ball - v
array.append(round(ball,2))
else:
ball = FLOOR
array.append(round(ball,2))
direction = 'UP'
v *= COEFFICIENT
count += 1
elif ball >= FLOOR and direction == 'UP':
v -= G
if (ball + v) >= FLOOR:
ball = ball + v
array.append(round(ball,2))
if v <= 0:
direction = 'DOWN'
else:
ball = FLOOR
array.append(ball)
direction = 'UP'
v *= COEFFICIENT
class textBouncy:
array = bounce()
def __init__(self, font, message, fontcolor, amount=10):
# Render the font message
self.base = font.render(message, 0, fontcolor)
# bounce amount (height)
self.amount = amount
#size = rect of maximum height/width of text
self.size = self.base.get_rect().inflate(0, amount).size
#normalise array to meet height restriction
self.array = [round(-x/(500/amount),2) for x in array]
def animate(self):
# create window surface s
s = pygame.Surface(self.size)
# height = max inflated height
height = self.size[1]
# define a step-sized rectangle in the location of the step
src = Rect(0, 0, self.base.get_width(), height)
# moves the message according to the array list.
dst = src.move(0, self.array[i])
if (i + 1) == len(self.array):
global i
i = 0
# blits the information onto the screen
s.blit(self.base, dst, src)
return s
entry_info = 'Bouncing ball text'
if __name__ == '__main__':
pygame.init()
#create text renderer
i = 0
array = bounce()
bigfont = pygame.font.Font(None, 60)
white = 255, 255, 255
renderer = textBouncy(bigfont, entry_info, white, 16)
text = renderer.animate()
#create a window the correct size
win = pygame.display.set_mode(text.get_size())
win.blit(text, (0, 10))
pygame.display.flip()
#run animation loop
finished = 0
while True:
pygame.time.delay(10)
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
sys.exit()
text = renderer.animate()
i += 1
win.blit(text, (0, 10)) # blits the finished product from animate
pygame.display.flip()
(Quote) "it all comes down to math really" Kay so you need to - the y axis when you want to make it go up and + the x axis to make it go side ways you could make it go up and down will moveing it horizontally and then when it reaches a point it will stop moving horizontally and just bonce up and down +ing it more every time
That was my 100$ which took me 5 mins to write
After revisiting this I managed to work this out - I needed to add everything I blitted down to compensate for the bounce up. So in the __init__function:
self.array = [round(-x/(500/amount),2)**+self.amount** for x in array]
Works perfectly now :)

Resources