game maker - how to navigate a map with 2d array - arrays

I have to make a navigable map
the starting point is in the center
there are three worlds + the final stage
pressing up I have to navigate from the base to the first level of the first world and go next level in second and third
pressing down I have do go from the third to the second and from the second to the first level and from the first level of the world to the base
pressing left and right I have to change the world
now:
I already made a lot of menus using different methods, but alway using a 1d array
obj_menu:
create event:
///menu
menu[0] = "new";
menu[1] = "load";
menu[2] = "exit";
space = 55;
mpos = 0;
step event:
///move
if(inputs) {
var move = 0;
move -= max(keyboard_check_pressed(vk_up),0);
move += max(keyboard_check_pressed(vk_down),0);
if(move != 0) {
mpos += move;
if(mpos < 0) {
mpos = array_length_1d(saveload) -1;
}
if(mpos > array_length_1d(saveload) -1) {
mpos = 0;
}
}
//push
if(keyboard_check_pressed(vk_enter)) {
scr_menu();
}
}
scr_menu();
switch(mpos) {
case 0: { scr_new_game(); break; } //new
case 1: { scr_load_game(); break; } //load
case 2: { game_end(); break; } //exit
default: { break; }
}
This time I have to navigate in a 2d array
I did this:
obj_map:
create event:
///navigation setup
if(crash_to_base) { lvl[0,0] = true }
if(base_to_ruins_1) { lvl[1,0] = true }
if(ruins_1_to_ruins_2) { lvl[1,1] = true }
if(ruins_2_to_ruins_3) { lvl[1,2] = true }
if(base_to_city_1) { lvl[2,0] = true }
if(city_1_to_city_2) { lvl[2,1] = true }
if(city_2_to_city_3) { lvl[2,2] = true }
if(base_to_lab_1) { lvl[3,0] = true }
if(lab_1_to_lab_2) { lvl[3,1] = true }
if(lab_2_to_lab_3) { lvl[3,2] = true }
if(base_to_castle) { lvl[4,0] = true }
//posizione del menu
mposh = 0;
mposv = 0;
mpos[mposv,mposh] = 0;
step event:
///map navigation
if(inputs) {
moveh -= max(keyboard_check_pressed(vk_left),0);
moveh += max(keyboard_check_pressed(vk_right),0);
movev -= max(keyboard_check_pressed(vk_up),0);
movev += max(keyboard_check_pressed(vk_down),0);
if(moveh != 0) {
//mposh += move;
}
if(movev != 0) {
//mposv += move;
}
push = keyboard_check_pressed(vk_enter);
if(push) {
scr_map();
}
}
how to translate the first method to de sencond need??

Not quite sure what your having difficulty with, perhaps you could elaborate on what exactly the problem is? On a side note however your 1D menu navigation code can be greatly simplified to:
mpos += keyboard_check_pressed(vk_up) - keyboard_check_pressed(vk_down);
var len = array_length_1d(saveload);
if (mpos < 0) { mpos = len - 1; }
if (mpos > len - 1) { mpos = 0; }
and in terms of a 2d map navigation system, it might not be beneficial to use 2d arrays and instead you could use a ds_map which allows you to store all information on each location in one data structure. For instance
var lvlMap = ds_map_create()
lvlMap[?"base-title"] = "Base"
lvlMap[?"base-travel-right"] = "crash"
lvlMap[?"base-travel-left"] = "fortress"
then when you try to move right/left:
var next_location = lvlMap[?current_location+"-travel-"+direction]
current_location = next_location

Related

fixing non-null String must be provided to a Text widget

I'm quite new in flutter.
I am working on a quiz app and try to make every quiz has five questions
I faced some problems :
1- I don't want to repeat the same question in the same quiz.[my quiz also start with question number one every time].
2- Every time it reaches my question number ten [which in array] nine my app crash.
NOTE: I'm using a JSON file to store my questions.
int j = 1;
int i = 1;
var random_array;
genrandomarray() {
var distinctIds = [];
var rand = new Random();
for (int i = 1;;) {
distinctIds.add(rand.nextInt(10));
random_array = distinctIds.toSet().toList();
if (random_array.length < 10) {
continue;
} else {
break;
}
}
print(random_array);
}
setState(() {
if (j < 5) {
i = random_array[j];
j++;
} else {
Navigator.of(context).pushReplacement(MaterialPageRoute(
builder: (context) => resultpage(marks: marks),
));
}
disableAnswer = false;
});
genrandomarray() {
var rand = new Random();
make it choose random between questions
var distinctIds = [i = rand.nextInt(10) + 1];
for (int i = 0;;) {
to not crash when it reach to 10 question
distinctIds.add(rand.nextInt(10) + 1);
random_array = distinctIds.toSet().toList();
if (random_array.length < 10) {
continue;
} else {
break;
}
}
print(random_array);
}

messagebox and timer in visual studio

Need help.
so i was making a game with my friend for college using visual studio 2017 and there's something weird about the program.
we're set it so that when the life is zero, a message box would show up and chose whether to retry the game or not, but when we tried the game, the message box show's up at least at 20 - 30 second after playing the game and the timer for the game is still going even though we add "timergame.enable = false;".
where's seems to be the problem?
private void timerGame_Tick(object sender, EventArgs e)
{
for (int i = 0; i < listOfSardine.Count; i++)
{
listOfSardine[i].Top += (int)listOfSardine[i].Tag;
if (listOfSardine[i].Bounds.IntersectsWith(pictureBoxGrass.Bounds))
{
userLives--;
labelLives.Text = "Lives: " + userLives;
listOfSardine[i].Dispose();
listOfSardine.RemoveAt(i);
if (userLives == 0)
{
highScore = userScore;
timerBonusSpeed.Enabled = false;
timerGame.Enabled = false;
timerHealth.Enabled = false;
timerMatatabi.Enabled = false;
timerSardine.Enabled = false;
DialogResult dialogResultLose = MessageBox.Show
("Sorry.... you have lost, continue?", "Continue??", MessageBoxButtons.YesNo);
if (dialogResultLose == DialogResult.Yes)
{
for (int j = 0; j < listOfHealth.Count; j++)
{
listOfHealth[j].Dispose();
}
listOfHealth.Clear();
for (int q = 0; q < listOfSardine.Count; q++)
{
listOfSardine[q].Dispose();
}
listOfSardine.Clear();
for (int k = 0; k < listOfMatatabi.Count; k++)
{
listOfMatatabi[k].Dispose();
}
listOfMatatabi.Clear();
userLives = USER_LIVES;
userScore = USER_SCORE;
timerBonusSpeed.Enabled = true;
timerGame.Enabled = true;
timerHealth.Enabled = true;
timerMatatabi.Enabled = true;
timerSardine.Enabled = true;
}
else
{
this.Visible = false;
FormMainMenu formMainMenu = new FormMainMenu();
formMainMenu.Owner = this;
formMainMenu.ShowDialog();
}
}
}
else if (listOfSardine[i].Bounds.IntersectsWith(pictureBoxMainCharacter.Bounds))
{
listOfSardine[i].Dispose();
listOfSardine.RemoveAt(i);
userScore += 1;
labelScore.Text = "Score: " + userScore;
if (userScore % 100 == 0)
{
listOfSardine[i].Top += (int)listOfSardine[i].Tag * 4;
}
if(userScore == 1000)
{
timerBonusSpeed.Enabled = false;
timerGame.Enabled = false;
timerHealth.Enabled = false;
timerMatatabi.Enabled = false;
timerSardine.Enabled = false;
highScore = userScore;
}
}
else
{
listOfSardine[i].Refresh();
}
}
for (int i = 0; i < listOfHealth.Count; i++)
{
listOfHealth[i].Top += (int)listOfHealth[i].Tag;
if (listOfHealth[i].Bounds.IntersectsWith(pictureBoxGrass.Bounds))
{
listOfHealth[i].Dispose();
listOfHealth.RemoveAt(i);
}
else if (listOfHealth[i].Bounds.IntersectsWith(pictureBoxMainCharacter.Bounds))
{
listOfHealth[i].Dispose();
listOfHealth.RemoveAt(i);
userLives++;
labelLives.Text = "Lives: " + userLives;
}
else
{
listOfHealth[i].Refresh();
}
Not enough clear what you did. However, I think you have a counter for life, and which are decreasing as per your game's event. On timer event just check life counter is equal or less than Zero or not. If so, just stop timer, give user confirmation for retry. If user want to retry, then reset life counter and start timer.
Ahh already found the answer
our problem is about the ownership of the form, we just incorrectly insert the ownership for each form
thanks for the people who have answered my question earlier

How can I use the array that I have at frame 1 to another frame?

When I'm going to draw the next stage at frame 2 my enemies did nothing.
When the stage1 finished I remove the listeners and at stage 2 I add it back.
So, How can I use the array that I have at frame 1 to another frame?
stop();
var enemy1Array:Array = new Array();
for (var e1:int = numChildren - 1; e1 >= 0; e1--)
{
var childe1:DisplayObject = getChildAt(e1);
if (childe1.name.indexOf("enemy")>-1)
{
enemy1Array.push(MovieClip(childe1));
MovieClip(childe1).hitPoints=enemykoufoueshitpoints;
}
}
stage.addEventListener(Event.ENTER_FRAME,loop);
function loop(event:Event):void
{
for(var e:int=enemy1Array.length-1;e>=0;e--)
{
if (playerrun == true)
{
enemy1Array[e].x -=speedall;
}
if (playerrunback == true)
{
enemy1Array[e].x +=speedall;
}
if (enemy1Array[e].hitTestPoint(player.x+5,player.y-40))
{
trace("i heart the player");
zoihit++;
enemy1Array[e].x +=70;
enemy1Array[e].gotoAndPlay(1);
}
if (enemy1Array[e].hitTestPoint(player.x-5,player.y-40))
{
trace("i heart the player");
zoihit++;
enemy1Array[e].x -=70;
enemy1Array[e].gotoAndPlay(1);
}
if (enemy1Array[e].hitTestObject(knife)&&attackright == true)
{
attackright = false;
enemy1Array[e].hitPoints -= knifedamage;
enemy1Array[e].gotoAndPlay(1);
}
if (enemy1Array[e].hitTestObject(knife)&&attackleft == true)
{
attackleft = false;
enemy1Array[e].hitPoints -= knifedamage;
enemy1Array[e].gotoAndPlay(1);
}
if (enemy1Array[e].hitPoints <= 0)
{
var thkiamantoui:thkiamanti= new thkiamanti;
diamondArray.push(thkiamantoui);
this.addChild(thkiamantoui);
thkiamantoui.gotoAndStop(2);
thkiamantoui.x = enemy1Array[e].x;
thkiamantoui.y = enemy1Array[e].y-5.05;
enemy1Array[e].parent.removeChild(enemy1Array[e]);
enemy1Array.splice(e,1);
}
if(enemy1Array[e].hitTestObject(dioswall))
{
enemy1Array[e].parent.removeChild(enemy1Array[e]);
enemy1Array.splice(e,1);
}
}
if(stage2.hitTestObject(playerhit))
{
stage.removeEventListener(Event.ENTER_FRAME,loop);
gotoAndPlay(2);
}
}

My if-statement doesn't work

It's either going to be "Riktig, bokstaven forekommer" for right letter chosen or otherwise. What have i done wrong, when i start it now none of the Messages show.
btnStart.addEventListener(MouseEvent.CLICK, start);
var feil:Array = new Array ;
var riktig:Array = new Array ;
var bokstav:Array = new Array ;
bokstav[0] = "b";
bokstav[1] = "r";
bokstav[2] = "e";
bokstav[3] = "v"
var txtBokstav:TextField = new TextField( );
txtBokstav.maxChars = 1;
txtBokstav.restrict = "a-z æ ø å";
txtBokstav.type = flash.text.TextFieldType.INPUT;
addChild(txtBokstav);
function start(evt)
{
var bokstavInn:String = String(txtBokstav.text);
if (txtBokstav.text.length == 1)
{
if (bokstav.indexOf(bokstavInn) >= 0)
{
txtUtskrift.text = "Riktig, bokstaven forekommer";
riktig.push(bokstavInn);
for (var i = 0; i < riktig.length; i++)
{
txtUtskrift.appendText(riktig[i] + ", ");
}
}
else
{
txtUtskrift.text = "Feil, bokstaven forekommer ikke";
feil.push(bokstavInn);
for (var l = 0; l < feil.length; l++)
{
txtUtskrift.appendText(feil[l] + ", ");
}
}
}
}
1) Are you sure that txtUtskrift is on the Stage and visible?
2) Make sure that start() is being called (use a breakpoint or trace)
3) As askmozo suggests, place trace statements in the possible flow of execution. So, at the beginning of the start function, and within each possible if condition. You might add an else for the text.length test:
function start( evt )
{
trace( "start()..." );
if (txtBokstav.text.length == 1)
{
// ... what you already have
}
else
{
trace( "txtBokstav length not valid:", txtBokStav.text.length );
}
trace( "...start()" );
}

AS3 - Remove spaces from an array for word game

I'm building a word search game using the following AS3 code. My problem is I need to have spaces in my array of words, so that I can have things like states names, but I need the spaces removed before the words go into the puzzle.
The other concern is also that when a person selects a word from the puzzle will it still match the word in the list even though the word in the list still has a space.
I've struggled with this for a few days now and could use some help.
I've pasted all appropriate code below, I believe. Thanks.
Rich
// words and grid
private var wordList:Array;
private var usedWords:Array;
private var grid:Array;
// sprites
private var letterSprites:Sprite;
private var wordsSprite:Sprite;
wordList = ("New York,New Jersey,South Carolina,North Carolina").split(",");
// set up the sprites
gameSprite = new Sprite();
addChild(gameSprite);
letterSprites = new Sprite();
gameSprite.addChild(letterSprites);
wordsSprite = new Sprite();
gameSprite.addChild(wordsSprite);
// array of letters
var letters:Array = placeLetters();
// create word list fields and sprites
for(var i:int=0;i<usedWords.length;i++) {
var newWord:TextField = new TextField();
newWord.defaultTextFormat = letterFormatForList;
if(i < 20){ // first list
newWord.x = listXposition;
newWord.y = i*spacingForList+listYposition;
} else { // second list
newWord.x = listXposition + 130;
newWord.y = i*spacingForList+listYposition - (20 * 19);
}
newWord.width = 135;
newWord.height = spacingForList;
newWord.text = usedWords[i];
newWord.selectable = false;
wordsSprite.addChild(newWord);
}
// set game state
dragMode = "none";
numFound = 0;
}
// place the words in a grid of letters
public function placeLetters():Array {
// create empty grid
var letters:Array = new Array();
for(var x:int=0;x<puzzleSize;x++) {
letters[x] = new Array();
for(var y:int=0;y<puzzleSize;y++) {
letters[x][y] = "*";
}
}
// make copy of word list
var wordListCopy:Array = wordList.concat();
usedWords = new Array();
// make 1000 attempts to add words
var repeatTimes:int = 1000;
repeatLoop:while (wordListCopy.length > wordsLeft) {
if (repeatTimes-- <= 0) break;
// pick a random word, location and direction
var wordNum:int = Math.floor(Math.random()*wordListCopy.length);
var word:String = wordListCopy[wordNum].toUpperCase();
x = Math.floor(Math.random()*puzzleSize);
y = Math.floor(Math.random()*puzzleSize);
var dx:int = Math.floor(Math.random()*3)-1;
var dy:int = Math.floor(Math.random()*3)-1;
if ((dx == 0) && (dy == 0)) continue repeatLoop;
// check each spot in grid to see if word fits
letterLoop:for (var j:int=0;j<word.length;j++) {
if ((x+dx*j < 0) || (y+dy*j < 0) || (x+dx*j >= puzzleSize) || (y+dy*j >= puzzleSize)) continue repeatLoop;
var thisLetter:String = letters[x+dx*j][y+dy*j];
if ((thisLetter != "*") && (thisLetter != word.charAt(j))) continue repeatLoop;
}
// insert word into grid
insertLoop:for (j=0;j<word.length;j++) {
letters[x+dx*j][y+dy*j] = word.charAt(j);
}
// remove word from list
wordListCopy.splice(wordNum,1);
usedWords.push(word);
}
// fill rest of grid with random letters
for(x=0;x<puzzleSize;x++) {
for(y=0;y<puzzleSize;y++) {
if (letters[x][y] == "*") {
letters[x][y] = String.fromCharCode(65+Math.floor(Math.random()*26));
}
}
}
return letters;
}
// player clicks down on a letter to start
public function clickLetter(event:MouseEvent) {
var letter:String = event.currentTarget.getChildAt(0).text;
startPoint = findGridPoint(event.currentTarget);
dragMode = "drag";
}
// player dragging over letters
public function overLetter(event:MouseEvent) {
if (dragMode == "drag") {
endPoint = findGridPoint(event.currentTarget);
// if valid range, show outline
outlineSprite.graphics.clear();
if (isValidRange(startPoint,endPoint)) {
drawOutline(outlineSprite,startPoint,endPoint,0xCCCCCC);
}
}
}
// mouse released
public function mouseRelease(event:MouseEvent) {
if (dragMode == "drag") {
dragMode = "none";
outlineSprite.graphics.clear();
// get word and check it
if (isValidRange(startPoint,endPoint)) {
var word = getSelectedWord();
checkWord(word);
}
}
}
// when a letter is clicked, find and return the x and y location
public function findGridPoint(letterSprite:Object):Point {
// loop through all sprites and find this one
for(var x:int=0;x<puzzleSize;x++) {
for(var y:int=0;y<puzzleSize;y++) {
if (grid[x][y] == letterSprite) {
return new Point(x,y);
}
}
}
return null;
}
// determine if range is in the same row, column, or a 45 degree diagonal
public function isValidRange(p1,p2:Point):Boolean {
if (p1.x == p2.x) return true;
if (p1.y == p2.y) return true;
if (Math.abs(p2.x-p1.x) == Math.abs(p2.y-p1.y)) return true;
return false;
}
// draw a thick line from one location to another
public function drawOutline(s:Sprite,p1,p2:Point,c:Number) {
var off:Point = new Point(offset.x+spacing/2, offset.y+spacing/2);
s.graphics.lineStyle(outlineSize,c);
s.graphics.moveTo(p1.x*spacing+off.x ,p1.y*spacing+off.y-3);
s.graphics.lineTo(p2.x*spacing+off.x ,p2.y*spacing+off.y-3);
}
// find selected letters based on start and end points
public function getSelectedWord():String {
// determine dx and dy of selection, and word length
var dx = endPoint.x-startPoint.x;
var dy = endPoint.y-startPoint.y;
var wordLength:Number = Math.max(Math.abs(dx),Math.abs(dy))+1;
// get each character of selection
var word:String = "";
for(var i:int=0;i<wordLength;i++) {
var x = startPoint.x;
if (dx < 0) x -= i;
if (dx > 0) x += i;
var y = startPoint.y;
if (dy < 0) y -= i;
if (dy > 0) y += i;
word += grid[x][y].getChildAt(0).text;
}
return word;
}
// check word against word list
public function checkWord(word:String) {
// loop through words
for(var i:int=0;i<usedWords.length;i++) {
// compare word
if (word == usedWords[i].toUpperCase()) {
foundWord(word);
}
// compare word reversed
var reverseWord:String = word.split("").reverse().join("");
if (reverseWord == usedWords[i].toUpperCase()) {
foundWord(reverseWord);
}
}
}
// word found, remove from list, make outline permanent
public function foundWord(word:String) {
sndSuccess=new success_sound();
sndSuccessChannel=sndSuccess.play(200);
so.data.totalWordsFound = so.data.totalWordsFound + 1;
so.flush();
// draw outline in permanent sprite
drawOutline(oldOutlineSprite,startPoint,endPoint,0xDDDDDD);
// find text field and set it to gray
for(var i:int=0;i<wordsSprite.numChildren;i++) {
if (TextField(wordsSprite.getChildAt(i)).text.toUpperCase() == word) {
TextField(wordsSprite.getChildAt(i)).textColor = 0x777777;
}
}
// see if all have been found
numFound++;
if (numFound == usedWords.length) {
if (so.data.difficulty == "Easy") {
so.data.easyWon = so.data.easyWon + 1;
}
if (so.data.difficulty == "Medium") {
so.data.mediumWon = so.data.mediumWon + 1;
}
if (so.data.difficulty == "Hard") {
so.data.hardWon = so.data.hardWon + 1;
}
so.flush();
endGame();
}
}
I'm hesitant to post an answer as I'm not really sure what's going on, but hopefully this info will help:
Keep your words in the arrays with spaces, that's a good idea. When you want to check against the words in your game, just convert both words to the same format using a function. eg:
var wordList:Array = ("New York,New Jersey,South Carolina,North Carolina").split(",");
var selectedWord:String = "NEWYORK";
// minWord converts all words to the same format of no spaces and all lower case.
function minWord(word:String):String {
return word.replace(/\s/g, "").toLowerCase();
}
// this loop checks all the words from your array against the selectedWord.
for each(var word:String in wordList) {
trace(minWord(word) + " == " + minWord(selectedWord) + "; ", minWord(word) == minWord(selectedWord));
}
Hope that helps!

Resources