2022-01-29 14:37:43

hi guys.
how are you all.
I'm planning to create a story game using Python.
Well, it's easy to make some story segments work, and get the user to interact with the dialogues by typing and choosing options.
However, I plan to make a map where the user will walk to a certain point to complete the story.
Are there ways to make maps?
Please do not mention Lucia Engine because it is full of bugs in its skripts.
I'm thinking of making my own map system, by starting from Scratch and teaching my program as a child learns to walk, eg playing a sound if a user presses a button to move and programming the tiles for this map, creating variables for the coordinates from scratch.
But this will take a long time.
Is there a ready-made mapping project that I can rely on?
Note: By the word map I don't mean a huge map with a lot of complications, dangers and player death, no, everything is a small map in which the user searches for the button to complete the story by moving with the arrows.

2022-01-29 16:14:45 (edited by bhanuponguru 2022-01-29 16:16:14)

use a 2d array for 2d maps, and 3d for 3d maps.
for example we have
air=0
concrete=1
carpet=2
map=[[air]*100]*100
then if you wan't to change any coordinates
map[5][10]=concrete
or add a tile for a range
for x in range(xrange):
    for y in range(yrange):
        map[x][y]=carpet
and do like
if map[player.x][player.y] == concrete: play_concrete_sound
you can also define tile name by string
concrete='concrete'
and do like play_sound(f'{map[player.x][player.y]}.wav')
but please define tile names in a variable because if you directly pass an integer or string, it wood recreate that and alocate a memory which wood consume more memory fore big maps.
you should not do this
map=[['air']*100]*100
it wood create 100*100, 10000 strings of air. instead if you did
air='air'
map=[[air]*100]*100
this wood not create 10000 strings, instead will use the variable that we created, hence defines only one string and thus saves large amounts of memory.

if you like this post, please thum it up!
if you like to see my projects, feel free to check out my github
if you want to contact me, you can do here by skype. or you can follow me on twitter: @bhanuponguru
discord: bhanu#7882

2022-01-29 16:31:06

@2.
oh this is really good things
any things else?

2022-01-29 16:42:11

I guess that's about all you'd need, unless there's a better way of handling maps.

best regards
never give up on what ever you are doing.

2022-01-29 17:40:42

@2.
so wait a minut
I write this code, but doesn't work

from winsound import PlaySound
air=0
concrete=1
carpet=2
map=[[air]*100]*100
xrange=100
yrange=100
for x in range(xrange):
    for y in range(yrange):
        map[x][y]=carpet

if map[x][y] == carpet:
    PlaySound(f'{map[x][y]}.wav', 1)

2022-01-29 17:48:31

so I do not understand, this is the second thing I did:

import lucia
air=0
concrete=1
carpet=2
map=[[air]*100]*100

for x in range(xrange):
    for y in range(yrange):
        map[x][y]=carpet
if map[player.x][player.y] == carpet:
play_sound(f'{map[player.x][player.y]}.wav')
it shos me error:
    for y in range(yrange):
SyntaxError: invalid character in identifier

2022-01-29 18:19:44 (edited by bhanuponguru 2022-01-29 18:24:01)

oh no, your doing it completely wrong.
i think you did not understood the thing
map[x][y] will return the tile number, which is an integer. then it combines .wav.
so lets say there is a concrete at map[x][y]
then map[x][y] returns 1
so, unless there is file called 1.wav in your directory, it'll not play. that's why i also told you to use string instead of an integer. like concrete='concrete'
then map[x][y] returns 'concrete'. then the name will become 'concrete.wav'
so your code should bee this.
from winsound import PlaySound
air='air'
concrete='concrete'
carpet='carpet'
map=[[air]*100]*100
xrange=100
yrange=100
for x in range(xrange):
    for y in range(yrange):
        map[x][y]=carpet
PlaySound(f'{map[x][y]}.wav', 1)

or else if you wan't to use your code, do this instead
from winsound import PlaySound
air=0
concrete=1
carpet=2
map=[[air]*100]*100
xrange=100
yrange=100
for x in range(xrange):
    for y in range(yrange):
        map[x][y]=carpet
if map[x][y] == carpet:
    PlaySound('carpet.wav', 1)
again, if you don't understand why this works, please ask because it's very importent to know why any code that we written is working.
edit:
@6
you did not define xrange and yrange in your code.

if you like this post, please thum it up!
if you like to see my projects, feel free to check out my github
if you want to contact me, you can do here by skype. or you can follow me on twitter: @bhanuponguru
discord: bhanu#7882

2022-01-29 19:18:23

@7.
ok, but when I try to test this map, it shos me cmd window for a second and exit

2022-01-29 21:41:43

Dude, Seriously, Go learn proper programming and please for god sake stop trying to jump on it by just getting examples and doing random things because you'll just fail and keep screaming I hate everyone when someone doesn't help you, It doesn't work like this. As it stands it exactly looks like you're just trying to write code while not understanding almost all important aspects of coding.

2022-01-30 01:02:33 (edited by magurp244 2022-01-30 10:10:07)

A map typically consists of a 2D array that holds various representational numbers. So, you'll usually want to create a map filled with zeroes, something like:

width = 10
height = 10
area = []
for y in range(0,height,1):
    area.append([])
    for x in range(0,width,1):
        area[y].append(0)

Now each zero represent a spot in the map, and each number you can place there represents a particular object. So 1 is a wall, 2 is a door, 5 is a rock, 6 is a chicken, etc. So, to play a particular sound for each spot on the map, you use your map as a reference. Lets say the player is at 5 by 5:

player = [5,5]

PlaySound(f'{area[player[1]][player[0]]}.wav',1)

What the play line does is take "area", which is the map, and uses the players x/y to find a particular spot in that map. That spot will then return a number, such as 2, or 5, so it will then play a file called "2.wav", or "5.wav". You can also do additional checks for things like collisions or object identification with those reference numbers.

-BrushTone v1.3.3: Accessible Paint Tool
-AudiMesh3D v1.0.0: Accessible 3D Model Viewer

2022-01-30 05:39:47

@magurp244, thanks a lot. Your explanations were very helpful and clear. Although I knew python quite well I had a block in the creation of audio games, which depended precisely on the map as I did not have a clear idea on how to represent it. I would like to ask you a few questions.
The first is: once this array is created, how do you change the values of a column? Let's say I want to place a wall from box 0, 5 to box 9, 5. So a vertical wall that will divide our array into 2. How to do?
Another question. I remember a post from Camlorn, which I could not understand at all, where he talked about compressing the arrays in order to save more memory. Could you explain to me how, once I have created my array which is the map?

2022-01-30 05:43:59

@10
Fun fact. In Python, you can multiply lists:

[0] * 10

Is a list of 10 zeros.

@11
You're asking how to write a pair of nested for loops, something like:

for i in range(min_x, max_x):
    for j in range(min_y, max_y):
        # set the tile

Which is very basic programming knowledge.  You're right that compression is a good idea, but you're not even close to ready to handle that level of complexity if you have to ask the question you're opening with.  First, you'll need to get as far as doing your map as a single, flat non-nested list, which you're also not ready for.  Get a game published or get far enough that you have a problem with how big your maps are, then come back.

My Blog
Twitter: @ajhicks1992

2022-01-30 05:46:25

ibraheemmohsen wrote:

@7.
ok, but when I try to test this map, it shos me cmd window for a second and exit

I asume you dont have a walking system in your code? I dont know what you have in your code. its hard to help.

End of Post!
Leos signing off.
CFN ID: LeosKhai. (Always looking to fight people)
Discord: leos_khai

2022-01-30 06:40:04 (edited by ambro86 2022-01-30 06:42:22)

@camlorn, I've sent you a pm. I've read the classic python examples that use for loops, but it confuses me to apply them to two-dimensional arrays. Not everyone may have an advanced understanding of python, or at least, everyone starts from the beginning, learning from mistakes. Perhaps a flaw in our field is that a well-structured guide is missing, as there was in bgt, which guides you from the very basics to the complete creation of an audio game, even if I understand that it is long to do.
In any case, I did some tests. Mine would be to change the data of only one column. It confuses me a little how to do it. I tried this but it doesn't work as I would like
air = 0
concrete = 1
wall = 2
map = [[air] * 10] * 10
for x in range (5):
for y in range (9):
map [x] [y] = wall

2022-01-30 07:33:54

@14, I don't understand how a for loop can be confusing, nor do I see how a nested for loop is confusing. Compression of maps is advanced stuff considering the knowledge of most of the people in this thread. Flattening N-d arrays into a single array is your first step. Then learning how bitwise operations work, and then learning how to use them properly, is the next. Camlorn and I aren't going to tell you how to do it because its beyond you right now.

"On two occasions I have been asked [by members of Parliament!]: 'Pray, Mr. Babbage, if you put into the machine wrong figures, will the right answers come out ?' I am not able rightly to apprehend the kind of confusion of ideas that could provoke such a question."    — Charles Babbage.
My Github

2022-01-30 07:37:44

I'm not saying there's a problem with where your knowledge is at.  Everyone starts somewhere.  I'm saying that when you're asking for info on compression, you're asking for info on how to write something as complicated as many small games that you don't need yet, and you probably don't realize how hard it is.  There's nothing wrong with asking for help on the basics, but I'm still going to come back and say "so actually this is really advanced and you're not ready" when there's something like 20 things between where you are and being ready to consider doing something like the things I've discussed on here.  I would expect anything close to the sorts of compression I've mentiond to be 100 to 200 lines minimum, and if you don't know what you're doing or how to benchmark effectively it'll come out horrendously slow and inefficient instead of being an improvement.  I'd suggest starting at trying to understand binary search trees if you want to go there, but if you think visualizing and working with a grid is hard then visualizing and working with a weird tree of grids but also the grids aren't just nested lists isn't going to be something you're going to have a rewarding time with right now.

My Blog
Twitter: @ajhicks1992

2022-01-30 07:41:28

@etin and @camlorn, I understand your answers. My current wish is not to understand how compression works, as I know it is an advanced topic. What interests me, once I know how to build a simple map, is how to build, for example a building. So my question is how to build a column of a wall. Because then from there I can build a building.

2022-01-30 07:47:39 (edited by amerikranian 2022-01-30 08:05:11)

First, guys. Please post your code in brackets. There's a link that reads "BBCode" right above the textbox if you don't know how.
Second, ibraheemmohsen, please make basic stuff first. It looks like you're skipping over a lot of crucial programming concepts. You'll really need classes, for instance. Also debugging skills. Also the ability to explain what errors you're getting instead of saying that something went wrong. We're not mind readers, you know.
@ambro86, I disagree. We don't need a BGT-like guide for Python because it's just going to lock people into the mindset that we have been pushing them out of, it being the fact that you don't need an audiogame-specific tutorial. That's partially the problem: When people get stuck they try to look for blind-specific concepts where there are none. The other problem is that people rarely actually read through a programming book in full. Your question about 2D arrays, for instance, shows that you haven't put together what is meant by indexing a list. Let's suppose we have a 5x5 list filled with zeros

matrix = [
    [0, 0, 0, 0, 0],
    [0, 0, 0, 0, 0],
    [0, 0, 0, 0, 0],
    [0, 0, 0, 0, 0],
    [0, 0, 0, 0, 0]
]

When you loop over it, the outer loop controls access to the first layer, or set of lists: consider this code:

matrix = [
    [0, 0, 0, 0, 0],
    [0, 0, 0, 0, 0],
    [0, 0, 0, 0, 0],
    [0, 0, 0, 0, 0],
    [0, 0, 0, 0, 0]
]
for i in range(len(matrix)):
    print(matrix[i]) # Outputs [0, 0, 0, 0, 0] every single time you iterate, regardless of index

If you picture a matrix as a box and think about what is happening, you'll see that your outer index is moving through the rows rather than the columns. This is why a lot of loops actually read as

for y in range(...):
    for x in range(...):
        # ...

Going back to the box analogy, if you stick a print instead of the comment above, like so,

matrix = [
    [0, 0, 0, 0, 0],
    [0, 0, 0, 0, 0],
    [0, 0, 0, 0, 0],
    [0, 0, 0, 0, 0],
    [0, 0, 0, 0, 0]
]
for y in range(5):
    print("New row")
    for x in range(5):
        print(matrix[y][x])

You'll get an output that looks like this (I only paste the first two rows because others are exactly the same)

New row
0
0
0
0
0
New row
0
0
0
0
0

So your outer index moves up and down through the first set of lists, while your inner index moves from left to right. It's still within exactly the same row every single time, hence a box. (Please forgive me for using "up" and "down", I'm fully aware that's not what is happening under the hood but that's my best shot at providing an explanation)
Quick recap. Your outer loop moves through rows, and your inner loop moves through columns. Your question of how to change a single column, then, should be relatively straight forward. Let's suppose we have the same 5x5 matrix and we want to change the middle column to ones

matrix = [
    [0, 0, 0, 0, 0],
    [0, 0, 0, 0, 0],
    [0, 0, 0, 0, 0],
    [0, 0, 0, 0, 0],
    [0, 0, 0, 0, 0]
]
for row in range(len(matrix)):
    matrix[row][2] = 1

print(matrix) # [[0, 0, 1, 0, 0]...]

Also, before you ask. No. It doesn't have to be a box. It could be a rectangle, like if I gave you a 5x3 matrix instead. The concept is still the same--you're accessing a list of lists. From here it's rather intuitive to derive the formula for accessing an element within a flattened array, but that is left as an exercise to the reader

2022-01-30 08:43:20 (edited by ambro86 2022-01-30 08:53:53)

Thanks Amerikranian, your post was very comprehensive. I'd like to ask you this. I was able to successfully change the value of a column by tweaking the example a bit. However, I was unable to change the value of a row.

air = 'air'
concrete = 'concrete'
carpet = 'carpet'
wall = 'wall'
map = [[concrete] * 10] * 10
#We want to change the central column
for row in range (len (map)):
    map [row] [4] = wall

What if I wanted to add another wall from 9.0 to 9.9 instead?
I specify that I have already done some tests, but without success.
Thanks again.

2022-01-30 09:00:33 (edited by magurp244 2022-01-30 10:10:21)

@19
Going from vertical to horizontal just involves shifting the loop a bit. For example:

for row in range (len (map)):
    map [row] [4] = wall

This goes from top to bottom, but if you want to go along a row you'd do this:

for row in range (len (map)):
    map [9] [row] = wall
-BrushTone v1.3.3: Accessible Paint Tool
-AudiMesh3D v1.0.0: Accessible 3D Model Viewer

2022-01-30 09:25:59

@magurp244, thanks, i tried as you say, but so it changes all the boxes of the matrix to wall. In fact, I too had tried so. But in this way not only changes from 9.0 to 9.9, but the whole matrix. Do you have another idea?

2022-01-30 09:28:11

The issue may be how your creating the map. While you can easily create a 1D array with something like:

box = [0]*10

You'll want to avoid nesting that like this:

box = [[0]*10]*10

The reason for this is that instead of creating 10 rows, it can end up creating 10 copies of one row. So if you change box[0][3] to 1, it changes that on every row. For example:

a = [[0]*5]*5
a[0][3] = 1
print(a)

Produces this:

[[0, 0, 0, 1, 0], [0, 0, 0, 1, 0], [0, 0, 0, 1, 0], [0, 0, 0, 1, 0], [0, 0, 0, 1, 0]]

So when making a 2D array, consider using it with a loop:

box = []
for a in range(0,5,1):
    box.append([0]*10)
-BrushTone v1.3.3: Accessible Paint Tool
-AudiMesh3D v1.0.0: Accessible 3D Model Viewer

2022-01-30 09:59:33

@magurp244 thanks! I succeeded, and I enjoyed creating a building on my map!

2022-01-30 12:35:45

@22
so wouldn't this work?
aa, i see now. but why is it doing this?
lets say it create copys of rows. but it should return a 2d array to a variable. so why it modify's all rows if we modify one row? is this how it works or what?

if you like this post, please thum it up!
if you like to see my projects, feel free to check out my github
if you want to contact me, you can do here by skype. or you can follow me on twitter: @bhanuponguru
discord: bhanu#7882

2022-01-30 13:22:48

Python is lazy, which means that it will try and save memory whenever it can. Multiplying the list like that just causes it to fill up with references to the original object because it’s no longer primitive and is treated as a reference. If your tiles were objects, you would get exactly the same behavior.