Related
I was making a game where you chop wood in a forest every day and was doing the function to destroy a tree after 3 seconds by putting a SysFont at the bottom of the screen, counting down from three seconds which by then it would remove the tree. I binded the key Q to chop down the first tree(for testing purposes), but instead I got no removal of the tree, and no SysFont counting down - all it did was lag the game because of the time.sleep(1) i had put in. The entire code is below:
import pygame
import time
pygame.init()
root = pygame.display.set_mode((603, 573))
pygame.display.set_caption("Homework")
window_is_open = True
white = (255, 255, 255)
black = (0, 0, 0)
width = 10
leaves_width = 30
height = 20
leaves_height = 10
x = 0
tree_trunk_x = 10
y = 0
tree_trunk_y = 10
vel = 5
brown = (150, 75, 0)
green = (58, 95, 11)
tree_one_property = True
tree_two_property = True
tree_three_property = True
tree_four_property = True
tree_five_property = True
tree_six_property = True
tree_seven_property = True
tree_eight_property = True
tree_nine_property = True
tree_ten_property = True
tree_eleven_property = True
tree_twelve_property = True
tree_thirteen_property = True
tree_fourteen_property = True
tree_fifteen_property = True
tree_sixteen_property = True
tree_seventeen_property = True
tree_eighteen_property = True
tree_nineteen_property = True
tree_twenty_property = True
tree_twenty_one_property = True
tree_twenty_two_property = True
tree_twenty_three_property = True
tree_twenty_four_property = True
tree_twenty_five_property = True
def create_tree(tree_x, tree_y, tree):
if tree:
trunk_x = tree_x + 10
trunk_y = tree_y + 10
pygame.draw.rect(root, brown, (trunk_x, trunk_y, width, height))
pygame.draw.rect(root, green, (tree_x, tree_y, leaves_width, leaves_height))
def destroy_tree(tree_property_name):
count = pygame.font.SysFont('Tahoma', 18, True, False)
countdown = count.render('3', True, (0, 0, 0))
root.blit(countdown, (590, 569))
pygame.display.update()
time.sleep(1)
count = pygame.font.SysFont('Tahoma', 18, True, False)
countdown = count.render('2', True, (0, 0, 0))
root.blit(countdown, (590, 569))
pygame.display.update()
time.sleep(1)
count = pygame.font.SysFont('Tahoma', 18, True, False)
countdown = count.render('1', True, (0, 0, 0))
root.blit(countdown, (590, 569))
pygame.display.update()
time.sleep(1)
tree_property_name = False
root.fill(white)
while window_is_open:
pygame.time.delay(100)
for event in pygame.event.get():
if event.type == pygame.QUIT:
window_is_open = False
keys = pygame.key.get_pressed()
if keys[pygame.K_RIGHT]:
x += vel
if keys[pygame.K_LEFT]:
x -= vel
if keys[pygame.K_UP]:
y -= vel
if keys[pygame.K_DOWN]:
y += vel
if keys[pygame.K_q]:
destroy_tree(tree_one_property)
root.fill(white)
font = pygame.font.SysFont('Tahoma', 18, True, False)
score = font.render('Score:', True, (0, 0, 0))
root.blit(score, (410, 0))
rectangle = pygame.draw.rect(root, (0, 0, 0), (x, y, width, 10))
tree_one = create_tree(0, 0, tree_one_property)
tree_two = create_tree(50, 0, tree_two_property)
tree_three = create_tree(100, 0, tree_three_property)
tree_four = create_tree(150, 0, tree_four_property)
tree_five = create_tree(200, 0, tree_five_property)
tree_six = create_tree(0, 50, tree_six_property)
tree_seven = create_tree(50, 50, tree_seven_property)
tree_eight = create_tree(100, 50, tree_eight_property)
tree_nine = create_tree(150, 50, tree_nine_property)
tree_ten = create_tree(200, 50, tree_ten_property)
tree_eleven = create_tree(0, 100, tree_eleven_property)
tree_twelve = create_tree(50, 100, tree_twelve_property)
tree_thirteen = create_tree(100, 100, tree_thirteen_property)
tree_fourteen = create_tree(150, 100, tree_fourteen_property)
tree_fifteen = create_tree(200, 100, tree_fifteen_property)
tree_sixteen = create_tree(0, 150, tree_sixteen_property)
tree_seventeen = create_tree(50, 150, tree_seventeen_property)
tree_eighteen = create_tree(100, 150, tree_eighteen_property)
tree_nineteen = create_tree(150, 150, tree_nineteen_property)
tree_twenty = create_tree(200, 150, tree_twenty_property)
tree_twenty_one = create_tree(0, 200, tree_twenty_one_property)
tree_twenty_two = create_tree(50, 200, tree_twenty_two_property)
tree_twenty_three = create_tree(100, 200, tree_twenty_three_property)
tree_twenty_four = create_tree(150, 200, tree_twenty_four_property)
tree_twenty_five = create_tree(200, 200, tree_twenty_five_property)
pygame.display.update()
pygame.quit()
It looks like you are drawing the font (almost) entirely off the bottom of the screen.The lines below:
root = pygame.display.set_mode((603, 573))
...
root.blit(countdown, (590, 569))
indicate that your screen has a height of 573 pixels. You are blit'ing your text with its top at 569, which is only 4 pixels onto the screen. In reality that likely means that the text is entirely off the bottom of the screen.
Try moving it a bit higher.
In fact you can actually get the size of the bounding box of the text surface countdown like this:
text_box_size = countdown.get_size()
See docs here. You can get the height and width of the text box like this and use that to determine the offset from the bottom of the screen you want to pass to blit().
I have edited this answer to add a response to the question in your comment asking why your tree was still rendering. This would be to much to add in a follow on comment.
In your code you have a method def destroy_tree(tree_property_name) and in it you try to update the variable tree_property_name and make it False. That would work if the variable was passed to the function as pass by reference, but in python that is not how arguments are passed. So when you set it to False inside the method all that does is change the value seen inside the scope of the method. The value seen by the caller of the function is not changed.
You can get more explanation by looking at the answer to How do I pass a variable by reference?:
Your code would be significantly cleaner if you made the trees into a class. It would also allow you to be able to change the internal values in the class when the class is passed into a method.
I would like to separate 2 elements far apart in Tkinter.
I have tried using column such that label_1 is column = 0, row = 0 and label 2 is column 19 and label 3 is column 20 but this still results in them being side by side in the middle. I have set my frame with pack(side =TOP).
I also tried using pack on my label such that label 2 & 3 are right and label 1 is left but still ended up with an unexpected result.
Hence is there a way to separate the 2 elements far apart?
Example
First I use a frame using pack() to display.
self.frameTop.pack(fill=BOTH, expand=NO)
Apparently the condition expand and fill played an important role in display the expected result.
The bottom shows the code for the layout of each element and its anchoring
# Monty Logo
self.icon = Label(self.frameTop, image = self.iconImage, font=('Zilla Slab', 16, 'bold'), borderwidth = 0, highlightthickness = 0, bg="#FFFFFF")
self.icon.pack(padx = 8, pady = 8, side = LEFT, anchor=NW)
# Use a canvas line to deine the cutting
self.labelSeperator = Separator(self.window, orient="horizontal")#Label(self.frameTop, bg="#000000", height= 2, width = int(ws)).pack(side= BOTTOM)
self.labelTitle_time = Label(self.frameTop, font=('Zilla Slab', 16), anchor = "w", borderwidth = 0, highlightthickness = 0, bg="#FFFFFF")
self.labelTitle_time.pack(padx=8,side = RIGHT, anchor=CENTER)
self.labelTitle_day = Label(self.frameTop, font=('Zilla Slab', 16, 'bold'), borderwidth = 0, highlightthickness = 0,bg="#FFFFFF")
self.labelTitle_day.pack(side = RIGHT, anchor=CENTER)
I am trying to adapt an application I found here, I imagined that I just had to add an axis. The problem is that the script seems like it is stuck. Can someone tell me what I did wrong and how I can use A* with a 3d matrix (i j k)?
this is the portion of the A* function I changed
for new_position in [(0, 0, 0), (0, 0, 1), (0, 1, 0), (0, 1, 1), (1, 0, 0), (1, 0, 1), (1, 1, 0), (1, 1, 1)]: # Adjacent squares, (-1, -1), (-1, 1), (1, -1), (1, 1)]: # Adjacent squares removed to ignor diagonal movement
# Get node position
node_position = (current_node.position[0] + new_position[0], current_node.position[1] + new_position[1], current_node.position[2] + new_position[2])
# Make sure within range
if node_position[0] > (len(maze) - 1) or node_position[0] < 0 or node_position[1] > (len(maze[len(maze)-1]) -1) or node_position[1] < 0 or node_position[2] > (len(maze) - 1) or node_position[2] < 0 or node_position[2] > (len(maze[len(maze)-1]) -1):
continue
# Make sure walkable terrain
if maze[node_position[0]][node_position[1]][node_position[2]] != 0:
continue
it was originally:
for new_position in [(0, -1), (0, 1), (-1, 0), (1, 0), (-1, -1), (-1, 1), (1, -1), (1, 1)]: # Adjacent squares
# Get node position
node_position = (current_node.position[0] + new_position[0], current_node.position[1] + new_position[1])
# Make sure within range
if node_position[0] > (len(maze) - 1) or node_position[0] < 0 or node_position[1] > (len(maze[len(maze)-1]) -1) or node_position[1] < 0:
continue
# Make sure walkable terrain
if maze[node_position[0]][node_position[1]] != 0:
continue
this is the whole script with my alterations:
import numpy as np
class Node():
"""A node class for A* Pathfinding"""
def __init__(self, parent=None, position=None):
self.parent = parent
self.position = position
self.g = 0
self.h = 0
self.f = 0
def __eq__(self, other):
return self.position == other.position
def astar(maze, start, end):
"""Returns a list of tuples as a path from the given start to the given end in the given maze"""
# Create start and end node
start_node = Node(None, start)
start_node.g = start_node.h = start_node.f = 0
end_node = Node(None, end)
end_node.g = end_node.h = end_node.f = 0
# Initialize both open and closed list
open_list = []
closed_list = []
# Add the start node
open_list.append(start_node)
# Loop until you find the end
while len(open_list) > 0:
# Get the current node
current_node = open_list[0]
current_index = 0
for index, item in enumerate(open_list):
if item.f < current_node.f:
current_node = item
current_index = index
# Pop current off open list, add to closed list
open_list.pop(current_index)
closed_list.append(current_node)
# Found the goal
if current_node == end_node:
path = []
current = current_node
while current is not None:
path.append(current.position)
current = current.parent
return path[::-1] # Return reversed path
# Generate children
children = []
for new_position in [(0, 0, 0), (0, 0, 1), (0, 1, 0), (0, 1, 1), (1, 0, 0), (1, 0, 1), (1, 1, 0), (1, 1, 1)]: # Adjacent squares, (-1, -1), (-1, 1), (1, -1), (1, 1)]: # Adjacent squares removed to ignor diagonal movement
# Get node position
node_position = (current_node.position[0] + new_position[0], current_node.position[1] + new_position[1], current_node.position[2] + new_position[2])
# Make sure within range
if node_position[0] > (len(maze) - 1) or node_position[0] < 0 or node_position[1] > (len(maze[len(maze)-1]) -1) or node_position[1] < 0 or node_position[2] > (len(maze) - 1) or node_position[2] < 0 or node_position[2] > (len(maze[len(maze)-1]) -1):
continue
# Make sure walkable terrain
if maze[node_position[0]][node_position[1]][node_position[2]] != 0:
continue
# Create new node
new_node = Node(current_node, node_position)
# Append
children.append(new_node)
# Loop through children
for child in children:
# Child is on the closed list
for closed_child in closed_list:
if child == closed_child:
continue
# Create the f, g, and h values
child.g = current_node.g + 1
child.h = ((child.position[0] - end_node.position[0]) ** 2) + ((child.position[1] - end_node.position[1]) ** 2)+((child.position[2] - end_node.position[2]) ** 2)
child.f = child.g + child.h
# Child is already in the open list
for open_node in open_list:
if child == open_node and child.g > open_node.g:
continue
# Add the child to the open list
open_list.append(child)
def main():
maze = np.zeros((12,12,12))
start = (10, 9, 9)
end = (1, 1, 1)
path = astar(maze, start, end)
print(path)
if __name__ == '__main__':
main()
A* can work with any number of dimensions; it's a graph traversal algorithm, and no matter how many dimensions your problem space has, connecting one position to another still produces a graph.
You have two problems with generating new nodes, however.
You included (0, 0, 0) in the list, so no change. You keep putting the current position back into the queue for consideration. That’s just busy work, because the current position is already in the closed list.
You never subtract from any of your coordinates, you only add. So your x, y and z values can only ever go up. If reaching your goal requires a path around an obstacle, then you have a problem here because all your version can ever do is move in one direction along any given axis.
In a 3 by 3 by 3 3D matrix, with the current position in the middle, there are 3 times 3 times 3 minus 1 == 26 positions you can reach with a single step. Your code reaches just 7 of those, plus one that stays put.
If you extract your tuples in the for new_position in [...] list into a separate variable and add some newlines, and re-arrange them a bit to group them by how many 1s you have in the tuple, you get the following definition. I renamed this to deltas, because it's not a new position, it's the change relative to the old position, or delta. I re-arranged your tuples to make it easier to group them logically:
deltas = [
(0, 0, 0), # no change,
(0, 0, 1), (0, 1, 0), (1, 0, 0), # add to a single axis
(0, 1, 1), (1, 0, 1), (1, 1, 0), # add to two axes
(1, 1, 1) # move in all 3 directions at once.
]
for delta in deltas:
# ...
You want to drop the first one ((0, 0, 0)), and you need to add -1 versions of the other variants. You need 26 different tuples, but writing those by hand gets to be cumbersome, really fast. You can use itertools.product() to generate these, instead:
from itertools import product
# combinations of -1, 0 and 1, filtering out the (0, 0, 0) case:
deltas = [d for d in product((-1, 0, 1), repeat=3) if any(d)]
Now, your comment next to the loop says:
# Adjacent squares removed to ignor diagonal movement
It's not entirely clear what you mean by this, because your original list of deltas includes diagonals ((0, 1, 1) moves both in the y and z directions, and you have tuples combining movement in the x plus y and the x plus z axes), and even one that moves diagonal by incrementing all 3 axes. If you only wanted to move up, down, left, right, forward, and backward, you want to restrict movement to a single axis at a time, and deltas should be:
# movement without diagonals
deltas = [
(1, 0, 0), (-1, 0, 0), # only x
(0, 1, 0), (0, -1, 0), # only y
(0, 0, 1), (0, 0, -1), # only z
]
Personally, I'd move the whole business of generating new positions to a separate method on the Node class:
def possible_moves(self, map):
x, y, z = self.x, self.y, self.z
for dx, dy, dz in DELTAS:
newx, newy, newz = x + dx, y + dy, z + dz
try:
if maze[newx][newy][newz] != 0:
yield Node(self, (newx, newy, newz))
except IndexError:
# not inside the maze anymore, ignore
pass
This method assumes that there is a DELTAS global variable that defines the possible moves, and is a generator; each time yield is reached a new Node() instance is returned to whatever is using this as an iterator (like a for loop would).
Then just use that method instead of the children = [] list you filled with the for new_position in ...: loop, so directly in the part that uses the original children list:
# Loop through children
for child in current_node.possible_moves(map):
# Child is on the closed list
for closed_child in closed_list:
if child == closed_child:
continue
# etc.
I am a new programmer using code sculptor with python 3. I have an animation project and one of the requirements is to change the background between two different settings 100 times
At the bottom, I've added print(i) to show what the problem with my code is. Basically, the "i" variable gets incremented, but it doesn't run the draw function, so the variable is incremented without the background changing. I've tried changing the positions of the draw function and nothing seems to be working. I am wondering if someone on this site could give me pointers on what to do in this situation. My overall goal is to run the program and have the background change as the train moves. You can see the program running by changing the values in the for loops to low values such as 1 and 1.
<pre>import simplegui
import time
def draw_handler(canvas):
global x
global flag
x = x+3
flag = flag + 2
if flag >= 320:
x = x-930
flag = -300
canvas.draw_circle([550,50], 40, 4, "yellow", "yellow")
points = [[0,500], [0,600], [600,600], [600,500]]
canvas.draw_polygon(points, 1, "black", "sienna")
points2 = [[155+x,325], [155+x,450], [455+x,450], [455+x,325]]
canvas.draw_polygon(points2, 1, "black", "deepskyblue")
points3 = [[155+x,250],[155+x,325],[235+x,325],[235+x,250]]
canvas.draw_polygon(points3, 1, "black", "deepskyblue")
canvas.draw_circle([190+x,470], 35, 4, "dimgrey","lightgray")
canvas.draw_circle([267+x,470], 35, 4, "dimgrey","lightgray")
canvas.draw_circle([344+x,470], 35, 4, "dimgrey","lightgray")
canvas.draw_circle([421+x,470], 35, 4, "dimgrey","lightgray")
points4 = [[120+x,225],[120+x,255],[265+x,255],[265+x,225]]
canvas.draw_polygon(points4, 1, "black", "black")
points5 = [[425+x,235], [425+x,325], [445+x,325], [445+x,235]]
canvas.draw_polygon(points5, 1, "black", "black")
canvas.draw_line([410+x,230], [460+x, 230], 7, "black")
canvas.draw_line([175+x,350], [427+x, 350], 2, "red")
canvas.draw_line([175+x,350], [175+x, 420], 2, "red")
canvas.draw_line([427+x,350], [427+x, 420], 2, "red")
canvas.draw_line([175+x,420], [427+x, 420], 2, "red")
global color
color = ""
global y
global i
i = 0
for i in range(100):
for i in range(20000):
i = i + 10
print(i)
if i <= 10000:
color = "aliceblue"
elif i > 10000:
color = "red"
elif i > 20000:
i = 0
frame = simplegui.create_frame('Testing', 600, 600)
frame.set_draw_handler(draw_handler)
frame.set_canvas_background(color)
x = 0
flag = 0
frame.start()</pre>
edit: Here is a direct link to the code in CodeSkulptor - https://py3.codeskulptor.org/#user302_ZF0cMFUoOAK9PvH.py
I'm using Corona SDK, Sublime Text 3, and Lua. My goal in this particular program is to make a visual novel app that changes when the player clicks on the text displayed at the bottom of the screen to progress to the next text entry, therefore continuing the story.
I set up a bunch of code for logo, title screen, and other things, that works perfectly. What I'm currently trying to do within the visual novel scene is to use a table to draw the text from by change the .TEXT property to select a certain value from the table, therefore selecting the text and making that the new text. Basically, something like... (some dummy code below)
novelText = display.newText (insert the parameters for old text and the old text)
--the variable used to call the value in the table
page = 1
dummy table Novel_pages = {
[1] = nil,
[2] = "new text"
}
(insert runtime event here that calls this function)
page = page + 1
novelText.text = Novel_pages[page]
display.newText(novelText)
That was just dummy code, so please don't mind the format. :) I just want to show how I attempted to call these values from the table, and to show what I was doing without having to make people look through all my code.
So everything works fine in Corona SDK simulator, with the text even changing just momentarily -- until one second later, I get a message that reads
"mainl.lua:160: bad argument #1 to 'newText' (string expected, got table)
stack traceback:
[C]: in function 'NewText'
main.lua:160: in function <main.lua: 156>
?: in function <?169>"
Now's the part where I give you all my code! I hope it's not too much, and that I specified the problem enough. I can't see where I made the error in the table, since it should be JUST replacing the .text and not all the other properties? And then displaying with the new text properties and not have to reference the table at all afterwards? Perhaps there's a problem with needing the program to process the .text change before displaying the visual novel text...
Anyway, please help me! I would appreciate knowing what went wrong here, or being proposed an alternative! And thank you so much :)
Here's the code -- everything starts in function sceneVN()! And please excuse my cringy dialogue ingame c: It's a practice project!
local store = require( "plugin.google.iap.v3" )
local composer = require("composer")
local scene = composer.newScene()
display.setStatusBar( display.HiddenStatusBar ) -- Removes status bar
coins = 5 -- variable that defines the number of coins player has in the game.It will be different
--in a stand alone game, but as a small app meant to demonstrate function, it's necessary to start off
--with a small, defined number in the beginning.
local logo = display.newImage("/Images/logo.png", 155, 275) --code for my personal logo, drawn by me.
--Not actually showcased in the video because of time limit.
logo.alpha = 0
local function makeTitleTrue()
logo:removeSelf()
print("menu should be TRUE")
titleScreen()
end
local function fadeOut()
transition.to(logo, {time = 1000, alpha = 0, onComplete = makeTitleTrue})
end
transition.to(logo, {time = 1000, alpha = 1, onComplete = fadeOut}) -- end of logo code
function titleScreen() -- beginning of title code, which is not managed as a separate scene
title = true
titleImg = display.newImage("/Images/vn_bg.png", 155, 275)
--titleWords = display.newImage("/Images/TitleWords.png", 155, 275)
--fix to flow towards the upper right corner.
local flare = display.newImage("/Images/flare2.png", 40, 30)
flare.xScale = .5
flare.yScale = .5
local flare2 = display.newImage("/Images/flare2.png", 400, 70)
flare2.xScale = .6
flare2.yScale = .6
local flare3 = display.newImage("/Images/flare2.png", -30, 100)
flare3.xScale = .4
flare3.yScale = .4
local flare4 = display.newImage("/Images/flare2.png", 100, 400)
flare4.xScale = .4
flare4.yScale = .4
local flare5 = display.newImage("/Images/flare2.png", 400, 400)
flare5.xScale = .3
flare5.yScale = .3
local flare6 = display.newImage("/Images/flare2.png", 250, 200)
flare6.xScale = .3
flare6.yScale = .3
local function moveFlare1()
transition.to(flare, {time=2000, x = math.random(-100, 450), y = math.random(-100, 700), onComplete = moveFlare1})
end
local function moveFlare2()
transition.to(flare2, {time=2000, x = math.random(-100, 450), y = math.random(-100, 700), onComplete = moveFlare2})
end
local function moveFlare3()
transition.to(flare3, {time=2000, x = math.random(-100, 450), y = math.random(-100, 700), onComplete = moveFlare3})
end
local function moveFlare4()
transition.to(flare4, {time=2000, x = math.random(-100, 450), y = math.random(-100, 700), onComplete = moveFlare4})
end
local function moveFlare5()
transition.to(flare5, {time=2000, x = math.random(-100, 450), y = math.random(-100, 700), onComplete = moveFlare5})
end
local function moveFlare6()
transition.to(flare6, {time=2000, x = math.random(-100, 450), y = math.random(-100, 700), onComplete = moveFlare6})
end
transition.to(flare, {time=2000, x = math.random(-100, 450), y = math.random(-100, 700), onComplete = moveFlare1})
transition.to(flare2, {time=2500, x = math.random(-100, 450), y = math.random(-100, 700), onComplete = moveFlare2})
transition.to(flare3, {time=2000, x = math.random(-100, 450), y = math.random(-100, 700), onComplete = moveFlare3})
transition.to(flare4, {time=2000, x = math.random(-100, 450), y = math.random(-100, 700), onComplete = moveFlare4})
transition.to(flare5, {time=2000, x = math.random(-100, 450), y = math.random(-100, 700), onComplete = moveFlare5})
transition.to(flare6, {time=2000, x = math.random(-100, 450), y = math.random(-100, 700), onComplete = moveFlare6})
--add options that can when the screen is tapped, tap on an option twice to select
-- start story
-- continue story
-- coin gambling
-- end game
if (title == true) then
Runtime:addEventListener("tap", sceneVN)
end
end
function forceQuit()
function quit()
os.exit()
end
timer.performWithDelay(1000,quit)
end
function sceneVNChapter2()
return
end
function sceneVN() -- the actual visual novel code itself
display.remove(titleImg)
--display.remove(titleWords)
display.remove(flare)
display.remove(flare2)
display.remove(flare3)
display.remove(flare4)
display.remove(flare5)
display.remove(flare6)
title = false
local coinSheetData =
{
width = 32,
height = 32,
numFrames = 8,
}
local coinimageSheet = graphics.newImageSheet( "/Images/spinning_coin.png", coinSheetData )
local sequenceData =
{
name= "spinning_coin",
start = 1,
count = 8,
time = 1000,
loopCount = 0
}
--the properties of the name plate that can be changed ingame by using ".text" property
local nameOptions =
{
text = "Frankenstein",
x = 165,
y = 450,
width = 310,
font = "Charlesworth.ttf",
fontSize = 22,
align = "left"
}
local bg = display.newImage("/Images/bg4.jpg", 155, 275)
textRect = display.newRect(155, 525, 325, 200)
textRect:setFillColor(.02, .02, .02)
textRect.alpha = .6
page = 1
local frames = display.newImage("/Images/windowframes_gold.png", 155, 275)
display.newText(nameOptions)
local VN_pages = {
[1] = nil,
[2] = "\"Then, seeing as this is a simulation of\n a visual novel dating sim, I have no\n choice but to ask you...\"",
[3] = "\"My lady, would you go on a date with me?\nFrankenstein... butler of the fineest noble,\nCadis Etrama di Raizel?\"",
[4] = "duck",
[5] = "duck",
[6] = "duck",
}
local displayNovelText = display.newText("\"I see. So I\'m supposed to pretend I am\na character in a multi-chapter phone\napp that you\'ve been reading...\"", 165, 500, "Goudy Old Style Regular.ttf", 17)
function changePage()
print("dang it")
page = page + 1
displayNovelText.text = VN_pages[page]
display.newText(displayNovelText)
end
textRect:addEventListener("tap", changePage)
if (coins < 10) then
coinsDigits = 2
else
if (coins > 9) and (coins < 100) then
coinsDigits = 3
else
if (coins > 99) and (coins < 1000) then
coinsDigits = 4
else
if (coins > 999) and (coins < 10000) then
coinsDigits = 5
else
if (coins > 9999) and (coins < 100000) then
coinsDigits = 6
end
end
end
end
end
cooin = display.newSprite(coinimageSheet, sequenceData)
cooin.x = 25
cooin.y = 30
cooin:play()
coinText = display.newText("1", 57 + 4 * coinsDigits, 32, "VCR_OSD_MONO_1.001.ttf", 25)
coinText.text = coins
coinTimer = timer.performWithDelay(2000, cooin, 1)
end
function choiceMade( event ) --the scenes where all the choices are made
if (event.action == "clicked") then
local i = event.index
if (i == 1) then
Runtime:removeEventListener()
titleScreen()
else
if (i == 2) then
system.openURL( "https://www.paypal.com/us/home" )
else
if (i == 3) then
return
end
end
end
end
end -- end of choice scenes
function Outofcoins()
--native alert lack of zero coins
local alertMessage = "Uh oh, looks like you've run out of coins! To continue reading the story, would you like to buy or gameble for coins?"
native.showAlert( "Out of coins!", alertMessage, {"Gamble for coins", "Purchase coins", "Exit to Menu"}, choiceMade)
end
if (coins == 0) then -- conditional branch that alerts Outofcoins if no coins left
Outofcoins()
end
function sceneGambleStart()
function earntCoins()
numberEarnt = 0
local coinsGot = display.newImage("/Images/coins_gold.png", 155, 275)
coinsGot.alpha = 0
local function fadeOutCoinsEart()
transition.to(logo, {time = 2000, alpha = 0})
display.remove(coinsGot)
end
local transitionFade = transition.to(logo, {time = 2000, alpha = 1, onComplete = fadeOutCoinsEarnt})
timer.performWithDelay(2000, transitionFade, 1)
coinText.text = coins + numberEarnt
end
local function gamblerIntro()
nameOptions.text = "Gambler"
local bg = display.newImage("/Images/bg4.jpg", 155, 275)
textRect = display.newRect(155, 525, 325, 200)
textRect:setFillColor(.02, .02, .02)
textRect.alpha = .6
local frames = display.newImage("/Images/windowframes_gold.png", 155, 275)
display.newText(nameOptions)
if (gambleVisit == false) then
display.newText("\"Welcome to the coin gambling shop!\nHere's your chance to earn free coins\nwithout having to use the app store!", 165, 500, "Goudy Old Style Regular.ttf", 17)
--display.newText("\"You can play here once a day if you\'ve\nNO coins in your inventory! You are\ngiven three tries at any game each visit.", 165, 500, "Goudy Old Style Regular.ttf", 17)
--display.newText("\"So, then! What games will you play\nin our shop today? \n \n", 165, 500, "Goudy Old Style Regular.ttf", 17)
else
display.newText("\"Welcome back, player! You have\nthree tries left. So, what games\nwill you try your hand at?", 165, 500, "Goudy Old Style Regular.ttf", 17)
end
end
local function sceneDiceRoll()
--local show background graphics
--draw dice on screen, with function ready to shake/transition on screen when accelerometer
--transition hands up and drop dice animation
-- if dice = # chosen then give coins
end
local function sceneCardChoose()
-- a function that defines the mechanics of the card game.
--draw several options on the screen:
--3 cards, earn 5 coins.
--6 cards, earn 15 coins.
--9 cards, earn 30 coins.
--The player needs 5 coins to read another chapter, but by increasing card numbers,
--depending on the player's choice, show the images of the cards (with whatever numbers, always set)
-- on the screen and allow the player to choose a card. Make a shuffling animation.
-- lay all the cards on the screen, now with randomised positions defined by a number.
--the player may choose one. Event listener, if the number defined = card number, the card flips,
--shows its number, and the player wins the coins. defer to earntCoins.
--if the player chooses the wrong card, show him a "WRONG CARD" result, and ask if he would like another
--round or to exit to the main shop.
return
end
local function sceneGuessNumber()
--this game is not created, but is a dummy function that's shown here. It's included in the
--options to show that if this were a real game, that's what it would look like
return
end
end
The error message says all you need:
"mainl.lua:160: bad argument #1 to 'newText' (string expected, got
table)
if you go to line 160 of your code you'll find the following:
display.newText(displayNovelText)
a few lines above you do this:
local displayNovelText = display.newText("sometext")
Refer to the display.newText documentation to find out how to use this function correctly.
https://docs.coronalabs.com/api/library/display/newText.html
You'll see that display.newText() does not return a string, but a text-object.
It also does not take a text-object as input. That's what the error message is telling you.
To access the text of displayNovelText you have to write displayNovelText.text which you can stuff into display.newText() among other options...
Please make sure you always read the documentation of functions you use. You cannot be successful if you don't know what you are dealing with.