Making a player "bump" from an enemy/hazard in GML - collision

I've been making an RPG with Game Maker Studio 2.0 for my kids and have got stuck on one major issue. Collisons with enemies and hazards. A general collison would cause the game to keep registering colisions and cause the player to immediately die. I am trying to replace my premilinary solution of warping the player to one safe spot in each room, which is not ideal-- so I created a few scripts to "bump" the player to safe area depending on which direction/side of enemy the player collided. I am not a great programmer and I tend to make code that is over-complicated. It almost works-- it just bumps the player in the same direction everytime-- to the left of the enemy. If anyone could examine these scripts and give me some hints, it would be much appreciated.
Code in enemy object for collsion with player:
var get_enemy_loc, player_side, col
get_enemy_loc = scr_enemy_pos(obj_scorpion)
player_side = scr_player_orient(get_enemy_loc[0],get_enemy_loc[1],obj_player.x,obj_player.y)
col = scr_check_block(get_enemy_loc[0],get_enemy_loc[1])
show_debug_message("Player X")
show_debug_message(obj_player.x)
show_debug_message("Player Y")
show_debug_message(obj_player.y)
show_debug_message("Enemy X")
show_debug_message(get_enemy_loc[0])
show_debug_message("Enemy Y")
show_debug_message(get_enemy_loc[1])
if player_side[0] = true and col[2] = false{
scr_shift_player(1)
}
else
if col[0] = false{
scr_shift_player(4)
}
else{
if col[3] = false{
scr_shift_player(3)
}
else{
scr_shift_player(2)
}
}
if player_side[1] = true and col[2] = false{
scr_shift_player(1)
}
else
if col[0] = false{
scr_shift_player(4)
}
else{
if col[1] = false{
scr_shift_player(2)
}
else{
scr_shift_player(3)
}
}
if player_side[2] = true and col[3] = false{
scr_shift_player(3)
}
else
if col[0] = false{
scr_shift_player(4)
}
else{
if col[2] = false{
scr_shift_player(1)
}
else{
scr_shift_player(2)
}
}
if player_side[3] = true and col[3] = false{
scr_shift_player(3)
}
else
if col[0] = false{
scr_shift_player(4)
}
else{
if col[1] = false{
scr_shift_player(2)
}
else{
scr_shift_player(1)
}
}
Script for enemy position:
function scr_enemy_pos(enemy_int){
var enemy_pos;
enemy_pos[0] = enemy_int.x;
enemy_pos[1] = enemy_int.y;
return enemy_pos;
}
Script for checking for blocking objects:
function scr_check_block(enemy_x,enemy_y){
var left_col, right_col, up_col, down_col;
var group;
check_left = enemy_x - 100
check_right = enemy_x + 100
check_up = enemy_y + 100
check_down = enemy_y - 100
if position_empty(check_left,enemy_y){
left_col = false}
else {
left_col = true
}
if position_empty(check_right,enemy_x){
right_col = false
}
else {
right_col = true
}
if position_empty(enemy_x,check_up){
up_col = false
}
else {
up_col = true
}
if position_empty(enemy_x,check_down){
down_col = false
}
else {
down_col = false
}
group[0] = left_col
group[1] = right_col
group[2] = up_col
group[3] = down_col
return group
}
Script for checking players orientation on collision:
function scr_player_orient(enemy_x,enemy_y,player_x,player_y){
var ne, se, nw, sw;
ne = false
se = false
nw = false
sw = false
var comb
if enemy_x <= player_x and enemy_y <= player_y{
nw = true
}
else{
nw = false
}
if enemy_x > player_x and enemy_y <= player_y{
ne = true
}
else{
ne = false
}
if enemy_x <= player_x and enemy_y > player_y{
sw = true
}
else{
sw = false
}
if enemy_x > player_x and enemy_y > player_y{
se = true
}
else{
se = false
}
comb[0] = nw
comb[1] = ne
comb[2] = sw
comb[3] = se
return comb;
}
Script for executing player "bump":
function scr_shift_player(dir){
if dir = 1{
obj_player.y = obj_player.y - 20
}
if dir = 2{
obj_player.x = obj_player.x + 20
}
if dir = 3{
obj_player.y = obj_player.y + 20
}
if dir = 4{
obj_player.x = obj_player.x - 20
}
}

Answered my own question. I solved this problem by updtating the collsion code and
using a different script. I threw out scr_player_orient and replaced it with scr_player_dir using the following code.
Updated collsion code in enemy object
ar get_enemy_loc, player_side, col
get_enemy_loc = scr_enemy_pos(obj_scorpion)
player_side = scr_player_dir(get_enemy_loc[0],get_enemy_loc[1])
col = scr_check_block(get_enemy_loc[0],get_enemy_loc[1])
show_debug_message("Player X")
show_debug_message(obj_player.x)
show_debug_message("Player Y")
show_debug_message(obj_player.y)
show_debug_message("Enemy X")
show_debug_message(get_enemy_loc[0])
show_debug_message("Enemy Y")
show_debug_message(get_enemy_loc[1])
if player_side[0] = true and col[1] = false{
scr_shift_player(2)
}
else{
scr_shift_player(4)
}
if player_side[1] = true and col[0] = false{
scr_shift_player(4)
}
else{
scr_shift_player(2)
}
if player_side[2] = true and col[2] = false{
scr_shift_player(2)
}
else{
scr_shift_player(3)
}
if player_side[3] = true and col[3] = false{
scr_shift_player(3)
}
else{
scr_shift_player(2)
}
And used this new script -- scr_player_dir
function scr_player_dir(enemy_x, enemy_y){
var left,right,up,down,comb
left = false
right = false
down = false
up = false
if enemy_x < obj_player.x{
right = true && left = false
}
else{
right = false && left = true
}
if enemy_y < obj_player.x{
down = true && up = false
}
else{
down = false && up = true
}
comb[0] = right
comb[1] = left
comb[2] = up
comb[3] = down
return comb
}
I hope this helps someone with the same problem

Related

how to place two images on two different markers in mapKit using swift

I want to change marker image in my MKPointAnnotation() and I have successfully changed my image but problem is that I have 2 marker points and I want to place ignitionon.png on point one and ignitionof.png on point two and my logic place ignitionon.png on both the points.
Code
if(self.doubelLocation) {
var pointOff = CLLocationCoordinate2D()
var pointOn = CLLocationCoordinate2D()
if(self.dateTime.count > 0) {
for(var i : Int = 0 ; i < self.dateTime.count ; i++) {
// print("Real status = \(self.dateTime[i])")
var fixTime = self.dateTime[i]
if(fixTime == self.dateTimeTwo) {
pointOff = CLLocationCoordinate2DMake(self.latt[i], self.lngg[i]);
print("pointOff = \(pointOff)")
//points.append(pointOf)
}
if(fixTime == self.dateTimeOne){
pointOn = CLLocationCoordinate2DMake(self.latt[i], self.lngg[i]);
print("pointOn = \(pointOn)")
//points.append(pointOf)
}
}
var points: [CLLocationCoordinate2D]
points = [pointOn, pointOff]
dispatch_async(dispatch_get_main_queue(), {
let geodesic = MKGeodesicPolyline(coordinates: &points[0], count: 2)
self.theMapView.addOverlay(geodesic)
let latDelta:CLLocationDegrees = 0.03
let lnggDelta:CLLocationDegrees = 0.03
UIView.animateWithDuration(1.5, animations: { () -> Void in
let span = MKCoordinateSpanMake(latDelta, lnggDelta)
let region1 = MKCoordinateRegion(center: points[0], span: span)
self.theMapView.setRegion(region1, animated: true)
self.ActivityIndicator.stopAnimating()
for(var i : Int = 0 ;i < points.count; i++){
var st = self.reportText[i]
// let theMarker = MKPointAnnotation()
//how to change marker color
//https://stackoverflow.com/questions/33532883/add-different-pin-color-with-mapkit-in-swift-2-1
let theMarker = MKPointAnnotation()
theMarker.coordinate = points[i]
// if(st == "IGNITION ON"){
if(i == 0){
theMarker.title = "Status : IGNITION OFF"
theMarker.subtitle = "\(self.locationOff)"
// theMarker.subtitle = "Date = , Reg#: "
self.theMapView.addAnnotation(theMarker)
let anView1:MKAnnotationView = MKAnnotationView()
anView1.annotation = theMarker
anView1.image = UIImage(named:"ignitionof")
anView1.canShowCallout = true
anView1.enabled = true
}
if(i == 1){
// theMarker = UIColor.greenColor()
theMarker.title = "Status : IGNITION ON"
theMarker.subtitle = "\(self.locationOn)"
// theMarker.subtitle = "Date = , Reg#: "
self.theMapView.addAnnotation(theMarker)
//how to change image of marker
//https://stackoverflow.com/questions/24467408/swift-add-mkannotationview-to-mkmapview
let anView:MKAnnotationView = MKAnnotationView()
anView.annotation = theMarker
anView.image = UIImage(named:"ignitionon")
anView.canShowCallout = true
anView.enabled = true
}
// }
}
})
})
}
}
func mapView(mapView: MKMapView, viewForAnnotation annotation: MKAnnotation) -> MKAnnotationView? {
if (annotation is MKUserLocation) {
//if annotation is not an MKPointAnnotation (eg. MKUserLocation),
//return nil so map draws default view for it (eg. blue dot)...
return nil
}
let reuseId = "test"
var anView = mapView.dequeueReusableAnnotationViewWithIdentifier(reuseId)
if anView == nil {
anView = MKAnnotationView(annotation: annotation, reuseIdentifier: reuseId)
anView!.image = UIImage(named:"ignitionon")
anView!.canShowCallout = true
}
var anView1 = mapView.dequeueReusableAnnotationViewWithIdentifier(reuseId)
if anView1 == nil {
anView1 = MKAnnotationView(annotation: annotation, reuseIdentifier: reuseId)
anView1!.image = UIImage(named:"ignitionof")
anView1!.canShowCallout = true
}
else {
//we are re-using a view, update its annotation reference...
anView!.annotation = annotation
}
return anView
}
I am following this Link:
Swift - Add MKAnnotationView To MKMapView
It's not the best way to handle multiple marker with different metadata.
You can't use mapView.dequeueReusableAnnotationViewWithIdentifier(reuseId) two times or more because in viewForAnnotation it is for only 1 view for each Point you have added in the stack.
Create a sub-class of MKPointAnnotation:
class CustomPointAnnotation: MKPointAnnotation {
var tag: String!
}
Create a Dictionary with all images:
var imagesPath : ["tag_1": "image_1.png", "tag_2": "image_2.jpg"]
Now in the delegate func, check Simply
if !(annotation is CustomPointAnnotation) {
return nil
}
and Handle the only one View you have:
let reuseId = "test"
var anView = mapView.dequeueReusableAnnotationViewWithIdentifier(reuseId)
if anView == nil {
anView = MKAnnotationView(annotation: annotation, reuseIdentifier: reuseId)
var customannotation = annotation as! CustomPointAnnotation
anView!.image = UIImage(named: imagesPath(customannotation.tag))
anView!.canShowCallout = true
}
An example to add a new Custom point is:
let aPoint = CustomPointAnnotation()
aPoint.coordinate = CLLocationCoordinate2DMake(40.730872, -73.003066)
aPoint.title = "Info1"
aPoint.subtitle = "Subtitle"
aPoint.tag = "tag_1"
mapView.addAnnotation(aPoint)

If raycast is not hitting an object - change the material color to white

I am working on a small school project in Unity for my IT classes.
I've created a script in Unityscript that shows specific GUI when the raycast hits and object with certain tag. I also want it to change the material color to yellow as soon as the raycast hits the object collider. This is the part I've managed to do.
Now I want my script to change the color back to white when the raycast stopped hitting the object colider but I can't think of any way to do this.
Could anyone help me please? Thanks in advance!
Here's my code - I know it's messy but it's my first time coding anything that's more complex.
Ah, since I was only testing it the material change is only on the "Wood" tag.
Working code thanks to Romain Soual:
#pragma strict
var rayLength : int = 2;
private var inventory : Inventory;
private var showGUI : boolean = false;
var bush : GameObject;
var player : GameObject;
var objHit : GameObject;
function Start()
{
inventory = GameObject.Find("First Person Controller").GetComponent(Inventory);
}
function Update()
{
var hit : RaycastHit;
var forward = transform.TransformDirection(Vector3.forward);
if(Physics.Raycast(transform.position, forward, hit, rayLength))
{
if(hit.collider.gameObject.tag == "Wood")
{
objHit = hit.collider.gameObject;
showGUI = true;
objHit.collider.gameObject.renderer.material.color = Color.yellow;
if(Input.GetKeyDown("e"))
{
inventory.wood++;
Destroy(hit.collider.gameObject);
showGUI = false;
}
}
else if(hit.collider.gameObject.tag == "Sticks")
{
showGUI = true;
if(Input.GetKeyDown("e"))
{
inventory.stick++;
Destroy(hit.collider.gameObject);
showGUI = false;
}
}
else if(hit.collider.gameObject.tag == "BushFull")
{
showGUI = true;
bush = (hit.collider.gameObject);
if(Input.GetKeyDown("e"))
{
inventory.berry += 5;
bush.GetComponent(BushController).berriesTaken = true;
showGUI = false;
}
}
else if(hit.collider.gameObject.tag == "Stones")
{
showGUI = true;
if(Input.GetKeyDown("e"))
{
inventory.stone++;
Destroy(hit.collider.gameObject);
showGUI = false;
}
}
else if(hit.collider.gameObject.tag == "Pickaxe")
{
showGUI = true;
if(Input.GetKeyDown("e"))
{
inventory.pickaxe++;
Destroy(hit.collider.gameObject);
showGUI = false;
}
}
else if(hit.collider.gameObject.tag == "Axe")
{
showGUI = true;
if(Input.GetKeyDown("e"))
{
inventory.axe++;
Destroy(hit.collider.gameObject);
showGUI = false;
}
}
else
{
objHit.collider.gameObject.renderer.material.color = Color.white;
showGUI = false;
}
}
else
{
objHit.collider.gameObject.renderer.material.color = Color.white;
showGUI = false; //jesli gracz oddali sie od obiektu to okienko "pick up" znika
}
}
function OnGUI()
{
if(showGUI == true)
{
GUI.Box(Rect(Screen.width / 2, Screen.height / 2, 100, 25), "Pick up ");
}
}
In your Update function, you can save the current object being colored in yellow in a variable highlightedGameObject and compare it to the last highlighted Game Object. If they differ, make the last one go white ; end the function by saving highlightedGameObject in a variable lastHighlightedGameObject.
var highlightedGameObject;
var lastHighlightedGameObject;
function Update () {
[...]
highlightedGameObject = hit.collider.gameObject;
highlightedGameObject.renderer.material.color = Color.yellow;
[...]
if (highlightedGameObject != lastHighlightedGameObject && lastHighlightedGameObject != null) {
lastHighlightedGameObject.renderer.material.color = Color.white;
}
lastHighlightedGameObject = highlightedGameObject;
}
I hope that helps =)

Debug Assertion Failed! Expression: invalid operator<

So I am making a Poker simulation and need to be able to rank the hands.
so I enumerated the card ranks(number) as
enum Rank{ace=1, two, three, four, five, six, seven, eight, nine, ten, jack, queen, king};
and everything works fine except that Aces should be high
so I changed it now to
enum Rank{ two=2, three, four, five, six, seven, eight, nine, ten, jack, queen, king, ace};
So this simulation has a Hand object(five cards) and I am trying to sort a vector of them by rank.
I am trying to sort (sort(vector<Hand>.begin(),vector<Hand>.end(), poker_rank) a vector of Hands with according to their hand ranks (flush, straight, etc).
It used to work and now it gives me the error above
There is a lot of code so I am not going to post it but anyone have any ideas why changing the enums might cause this error especially since the function poker_rank is still fine and everything still works?
Here is everything
the getRank method returns the rank of the hand 9=straightflush 8=four of a kind 7=fullhouse 6=flush 5=straight 4=three of a kind 3=two pair 2=pair 1=unordered
my poker_rank
bool poker_rank(const Hand& first, const Hand& second){
Card midCard1 = first.getHand().at(2);
Card lastCard1 = first.getHand().back();
Card midCard2 = second.getHand().at(2);
Card lastCard2 = second.getHand().back();
if(first.getRank() > second.getRank()){
return true;
}
if(first.getRank() == second.getRank()){
if(first.getRank()==9){
return lastCard1 > lastCard2;
}
if(first.getRank()==8){
return fullFourCheck(first, second);
}
if(first.getRank()==7){
return fullFourCheck(first, second);
}
if(first.getRank()==6){
}
if(first.getRank()==5){
return straightRank(first, second);
}
if(first.getRank()==4){
}
if(first.getRank()==3){
return twoPairRank(first, second);
}
if(first.getRank()==2){
return pairRank(first, second);
}
if(first.getRank()==1){
}
}else{
return false;
}
return false;
}<code>
the helper methods
<pre>bool fullFourCheck(const Hand& first, const Hand& second){//This Works!
Card firstCard1 = first.getHand().front();
Card midCard1 = first.getHand().at(2);
Card lastCard1 = first.getHand().back();
Card firstCard2 = second.getHand().front();
Card midCard2 = second.getHand().at(2);
Card lastCard2 = second.getHand().back();
if(midCard1 > midCard2){
return true;
}
if(midCard1 == lastCard1){
if(midCard2==lastCard2){
return firstCard1 > firstCard2;
}
if(midCard2==firstCard2){
return firstCard1 > lastCard2;
}
}
if(midCard1 == firstCard1){
if(midCard2==lastCard2){
return lastCard1> firstCard2;
}
if(midCard2==firstCard2){
return lastCard1 > lastCard2;
}
}
return false;
}
bool straightRank(const Hand& first, const Hand& second){//This WORKS!
Card firstCard1 = first.getHand().front();
Card lastCard1 = first.getHand().back();
Card firstCard2 = second.getHand().front();
Card lastCard2 = second.getHand().back();
if(firstCard1.rank_==1 && firstCard2.rank_==1){
if(lastCard1.rank_==13 && lastCard2.rank_==5){
return true;
}else{
return false;
}
}
else if((firstCard1.rank_==1 && lastCard1.rank_==13)
||(firstCard2.rank_==1&&lastCard2.rank_==5)){
return true;
}
else if((firstCard1.rank_==1 && lastCard1.rank_==5)
||(firstCard2.rank_==1&&lastCard2.rank_==13)){
return false;
}
else{
return lastCard1 > lastCa`enter code here`rd2;
}
}
bool twoPairRank(const Hand& first, const Hand& second){//This WORKS!
Card firstCard1 = first.getHand().front();
Card secondCard1 = first.getHand().at(1);
Card midCard1 = first.getHand().at(2);
Card fourthCard1 = first.getHand().at(3);
Card lastCard1 = first.getHand().back();
Card firstCard2 = second.getHand().front();
Card secondCard2 = second.getHand().at(1);
Card midCard2 = second.getHand().at(2);
Card fourthCard2 = second.getHand().at(4);
Card lastCard2 = second.getHand().back();
if(secondCard1.rank_==1 && secondCard2.rank_!=1){
return true;
}
if(fourthCard1 > fourthCard2){
return true;
}
if(fourthCard1==fourthCard2){
if(secondCard1>secondCard2){
return true;
}
if(secondCard1==secondCard2){
if(midCard1==secondCard1 && midCard2==secondCard2){
return firstCard1 > firstCard2;
}
if(midCard1==secondCard1 && midCard2==fourthCard2){
return firstCard1 > lastCard2;
}
if(midCard1==fourthCard1 && midCard2==secondCard2){
return lastCard1 > firstCard1;
}
if(midCard1==fourthCard1 && midCard2==fourthCard2){
return lastCard1 > lastCard2;
}else{
return midCard1 > midCard2;
}
}
}
return false;
}
bool pairRank(const Hand& first, const Hand& second){//This WORKS!
Card pairInFirst;
Card pairInSecond;
for(int i = 0; i < first.size()-1; i++){
if(first.getHand().at(i)==first.getHand().at(i+1)){
pairInFirst = first.getHand().at(0);
break;
}
}
for(int i = 0; i < second.size()-1; i++){
if(second.getHand().at(i)==second.getHand().at(i+1)){
pairInSecond = first.getHand().at(0);
break;
}
}
vector<Card> firstTemp;
vector<Card> secondTemp;
if((pairInFirst > pairInSecond)||(pairInFirst.rank_==1 && pairInSecond.rank_!=1)){
return true;
}else if(pairInFirst==pairInSecond){
for(int i = 0; i < first.size(); i++){
if(!(first.getHand().at(i)==pairInFirst)){
firstTemp.push_back(first.getHand().at(i));
}
}
for(int i =0; i < second.size(); i++){
if(!(second.getHand().at(i)==pairInSecond)){
secondTemp.push_back(second.getHand().at(i));
}
}
}
return false;
}<code>

sorting showing unexpected results

I am sorting a grid with knockout.js. Following is my sort function
this.sortByName = function() {
var event = arguments[1];
var targeElement = event.originalTarget;
// console.info(targeElement);
console.log(targeElement.attributes[1].nodeValue);
order = 'sorting';
configuration.data.sort(function(a, b) {
if(a.name<b.name){
order = 'sorting_desc';
return a.name > b.name ? -1 : 1;
}
else if(a.name>b.name){
order = 'sorting_asc'
return a.name < b.name ? -1 : 1;
}
});
$(targeElement).removeClass('sorting_asc sorting_desc').addClass(order);
};
The by default grid view
The Sorted image 1
The sorted image 2
As you can see the order of sorting is not correct. I have been playing around for 3 days in this issue.
Well I found a solution to this problem
this.sortByName = function() {
currentOrder = arguments[0].sortClass();
var sortColumn = arguments[0].rowText;
if(currentOrder =='sorting' || currentOrder =='sorting_desc'){
currentOrder='sorting_asc';
configuration.data.sort(function(a, b) {
if (a[sortColumn] == b[sortColumn])
return 0;
else if (a[sortColumn] < b[sortColumn])
return -1;
else
return 1;
});
}else{
currentOrder='sorting_desc';
configuration.data.sort(function(a, b) {
if (a[sortColumn] == b[sortColumn])
return 0;
else if (a[sortColumn] > b[sortColumn])
return -1;
else
return 1;
});
}
self.resetSortColumns();
arguments[0].sortClass(currentOrder);
};

a puzzle game algorithm in as3

I am creating game like http://www.puzzlegames.org/814games-Connect-2-Game-game.html. so what should i add in connected() function?
fB and sB are First and second button selected.
fBN and sBN are names of those buttons.
allNull() makes fB,sB, fBN, sBN null.
function onClick(e:MouseEvent):void {
if (! another) {
another = true;
fB = e.target;
fBN = e.target.name;
}
else {
sB = e.target;
sBN = e.target.name;
if (fBN == sBN)
{
allNull();
}
else if (connected())
{
fB.removeEventListener(MouseEvent.MOUSE_DOWN, onClick);
sB.removeEventListener(MouseEvent.MOUSE_DOWN, onClick);
fB.alpha = 0;
sB.alpha = 0;
pairCount++;
allNull();
if (pairCount == 25)
{
gameOver = false;
showScore();
endGame();
}
}
another = false;
}
}
Please help. I am trying to solve this problem since 15 days.
Thanks in advance.

Resources