在复杂板上拖放Angular(矩阵) [英] Drag and Drop in Angular on complex board (matrix)

查看:88
本文介绍了在复杂板上拖放Angular(矩阵)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

所以我想在Angular中制作我的《 Battleships》游戏版本,并且需要一个10x10的矩阵,可以在其中拖放船只(如果您玩过游戏,您就知道我在说什么),我我正在使用Angular Cdk,但我根本无法使它工作.

So I want to make my version of the Battleships game in Angular and to do that I need a 10x10 matrix in which I can drag and drop the ships ( if you played the game you know what I am talking about ) and I'm using the Angular Cdk but I cannot make it work at all.

到目前为止,我已经尝试过使用divs制作表格,将元素放在一边,然后将它们拖放到板上,但是我无法连接这两个数组,因为船的数组不是嵌套的,而板子是嵌套的.

What I have tried so far is make a table out of divs, ships elements aside and drag and drop them on the board but I can't connect the two arrays because the array of ships is not nested and the board is.

这是stackblitz示例的链接: https://stackblitz.com/edit/angular-pp24ad

Here is the link to the stackblitz example : https://stackblitz.com/edit/angular-pp24ad

值得注意的是,矩阵中填充了IBox,这些IBox将在以后的游戏实现中提供帮助.我不确定是否需要更改飞船的数据结构.例如,作为另一个矩阵,我可以从中提取船只并转移到董事会,但仍然无法确定拖动的方向.我仍然不确定这是否是解决此问题的最佳方法,因此我愿意改变解决问题的方法.

It is noticeable that the matrix is filled with IBoxes which will help later during the game implementation. I am not sure if I have to change the data structure of the ships. For example to be another matrix from which I take the ships and transfer to the board but still, I can't figure out the dragging. I am still not sure that this is the best way to solve this problem so I am willing to change the way to solve the problem.

推荐答案

您需要定义两个"cdkDropList".cdkDropList不一定是列表,在您的情况下,您可以为可用船"设置一个简单的div,并为style:relative设置一个div,因为您要将船"放置在绝对位置.

You need has defined two "cdkDropList". A cdkDropList it's not necesary a list, in your case you can has a simple div for the "Available ships", and a div with style position:relative because you want to place the "ships" in a position absolute.

作为一个想法,在cdkDropList之间传递的数据是具有名称,大小,顶部和左侧的对象,因此(假设您有一个运输组件").记住,角工作关系到模型(ts中的变量)和视图(我们如何显示此变量)之间的关系.所以这个想法是有两个数组,并将元素从一个数组传递到另一个数组

As idea, the data to pass between cdkDropList are object with name, size, top and left, so (imagine you has a "ship-component"). Remember, Angular work relations the model (variables in ts) and the view (how we show this variables). So the idea is has two arrays and pass elements from one to another

Availables船是

The Availables ships is

<div cdkDropList #cdkShips=cdkDropList 
        [cdkDropListData]="ships" class="ship-list"
        [cdkDropListConnectedTo]="[cdkBoard]" 
        (cdkDropListDropped)="drop($event)" 
        cdkDropListSortingDisabled="true">

        <ng-container *ngFor="let ship of ships">
            <div cdkDrag [style.size]="50*ship.size+'px'">
                <app-ship [name]="ship.name" [size]="ship.size"></app-ship>
                <div *cdkDragPlaceholder></div>
            </div>
        </ng-container>
    </div>

板"是

<div cdkDropList #cdkBoard=cdkDropList style="position:relative" 
     [cdkDropListData]="shipsInBoard" 
     [cdkDropListConnectedTo]="[cdkShips]"
     (cdkDropListDropped)="drop($event)" 
     cdkDropListSortingDisabled="true">

    <ng-container *ngFor="let ship of shipsInBoard">
        <div style="position:absolute" 
            [style.top]="ship.top+'px'" 
            [style.left]="ship.left+'px'" cdkDrag>
            <app-ship [name]="ship.name" [size]="ship.size"></app-ship>
            <div *cdkDragPlaceholder></div>
        </div>
    </ng-container>

    <!---this it's only to draw the board-->
    <div class="row" *ngFor="let row of board;let i=index">
        <div class="cell" *ngFor="let box of row;let j=index" id='columns'>
            <button #bt mat-button class="bt-cell" 
              (mouseover)="position=bt.getBoundingClientRect()">
            </button>
        </div>
    </div>
</div>

请参见

  1. 在面板"中,我们使用[style.top]和[style.left]放置船"
  2. 我们已经定义了[cdkDropListConnectedTo] ="[cdkBoard]"和[cdkDropListConnectedTo] ="[cdkShips]"
  3. 我们有两个数组-将要交换的数据:船和shipsInBoard

drop事件是谁赋予顶部和左侧以及之后的值,交换数组中的元素

The drop event is who give value to top and left and after, interchange the elements in the arrays

  drop(event: CdkDragDrop<string[]>) {
      event.previousContainer.data[event.previousIndex].top=this.position?
            this.position.y-this.boardElement.nativeElement.getBoundingClientRect().y:
            0
      event.previousContainer.data[event.previousIndex].left=this.position?
        this.position.x-this.boardElement.nativeElement.getBoundingClientRect().x:
            0

    if (event.previousContainer === event.container) {
      moveItemInArray(
        event.container.data,
        event.previousIndex,
        event.currentIndex
      );
    } else {
      transferArrayItem(
        event.previousContainer.data,
        event.container.data,
        event.previousIndex,
        event.currentIndex
      );
    }
  }

我像这样制作一个傻瓜"应用程序船

I make a "fool" app-ship like

<div class="ship-box" [style.width]="52*size+'px'"  >
        {{name}}
   <div class="ship-drop-wrapper">
      <div *ngFor="let i of [0,1,2,3,4].slice(0,size)" class="ship-box-cell" 
        (mouseover)="index=i">
      </div>
   </div>
</div>

您可以看到 stackblitz

注意:您会注意到,将船拖到板上时,它位于您期望的上方的一行中.这是因为可用的船只"改变了高度

NOTE: You'll note that when you drag a ship to board, it is place in a row above you expect. It's because the "available ships" change the heigth

注意2:您需要在轮船"上添加一个新属性旋转"以在旋转位置显示-use [style.transform] ='rotate(90deg)'-

NOTE2: you early need add a new property "rotate" to your "ships" to show in rotate position -use [style.transform]='rotate(90deg)'-

这篇关于在复杂板上拖放Angular(矩阵)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆